Shop OBEX P1 Docs P2 Docs Learn Events
Using an Array Element as an Array Index — Parallax Forums

Using an Array Element as an Array Index

JonnyMacJonnyMac Posts: 9,214
edited 2009-02-15 23:36 in General Discussion
Given this kind of declaration:

tmpArray        VAR     Byte (9)
tmpIdx          VAR     tmpArray(8)


... couldn't SX/B allow tmpIdx to be used as an index into tmpArray?

tmpArray(tmpIdx) = X


... where X is evaluated and moved into __PARAM1 -- this code seems to work:

MOV   FSR, #tmpArray
ADD   FSR, tmpIdx
MOV   IND, __PARAM1
MOV   FSR, #__DEFAULT


My suggestion is that if the an array element can be used as an index into an array that it's part of -- knowing nothing about how the compiler validates and generates code I don't know if this is a reasonable request or not.

Comments

  • JonnyMacJonnyMac Posts: 9,214
    edited 2009-02-15 19:12
    Continuing the thought -- with full recognition that Assembly is not my first language -- could an element of another array be used (so long as it's aliased) if the did this:

    MOV   FSR, #idx2
    MOV   __PARAM4, IND
    MOV   FSR, #tmpArray
    ADD   FSR, __PARAM4
    MOV   IND, __PARAM1
    MOV   FSR, #__DEFAULT
    


    In this case idx2 is an element of another array.
  • Peter VerkaikPeter Verkaik Posts: 3,956
    edited 2009-02-15 21:12
    Jonnymac,

    I had simular thoughts expressed in the beta forum.
    Here is what I came up with then:

    Hi,
    I know it is not supported to use an array variable as index into an array variable.
    Example:
    DEVICE SX28, OSC4MHZ
     
    Glob var byte
    WGlob var word
    Norm var byte
    WNorm var word
    Arr var byte (1)
    Index var byte (1)
    Waste var byte (13)
    WArr var byte (2) span
    Index2 var byte (1)
     
    WArr(Norm) = Arr(Index) + WArr(Index2)
    
    

    throws error INVALID NUMBER OF PARAMETERS.

    But I think I figured out a way to make it happen. In fact, the solution is equal
    to the way large arrays on the sx28 are implemented.

    Here is the code that implements the above formula on the sx28:
      'WArr(Norm) = Arr(Index) + WArr(Index2)
    asm
      MOV FSR,#index                
      MOV FSR,IND                     
      AND W,#$F0                    
      ADD FSR,W                     
      ADD FSR,#Arr                     
      SETB FSR.4                    
      MOV __PARAM1,IND              
      BANK $00  
                        
      MOV FSR,#index2               
      MOV FSR,IND                     
      AND W,#$F0                    
      ADD FSR,W                     
      ADD FSR,#WArr                     
      SETB FSR.4                    
      ADD __PARAM1,IND              
      BANK $00 
    endasm                     
      WArr(Norm) = __PARAM1                   
    
    

    Resume:
    To get the address of an array element whose index·is also an array element
    (in pseudo code: fsr = @Arr(index) )

      ;SX18/20/28: fsr = Arr(Index)
      MOV FSR,#index                
      MOV FSR,IND                     
      AND W,#$F0                    
      ADD FSR,W                     
      ADD FSR,#Arr                     
      SETB FSR.4                    
    

      ;SX48/52: fsr = Arr(Index)
      MOV FSR,#index                
      MOV FSR,IND                     
      ADD FSR,#Arr       
    

    It looks to me the restriction that an array index must be a normal variable
    is easy to resolve (without using any __PARAMx variable).

    Jonnymac,
    Your last example could be done without using __param4 by doing
    mov fsr,#idx2
    mov fsr,ind ;your __param4 value
    add fsr,#tmpArray
    mov ind,__param1

    The key point is to calculate fsr without using any temporary variables.


    regards peter
  • David BaylissDavid Bayliss Posts: 58
    edited 2009-02-15 22:23
    In the case where the index of the nested array is constant it is easy as you say. In fact for the (fairly common) case where the array is contained within a single bank I believe you can do:

    ·mov fsr,#idx
    ·mov w,#arr1
    ·add w,ind
    ·mov fsr,w

    it is a little more exciting which the index of the nested array is variable to arr1[noparse]/noparse]arr2[noparse][[/noparse]i = 42 but still not impossible:

    arr1 equ $3a 
    arr2 equ $5a 
    i equ $a 
    val equ $8 
    org 0 
    reset Start 
    Start: 
    ; Preamble to allow 'stepping through' in SXSIM
    mov i,#2 
    mov fsr,#arr2+2 
    mov ind,#3 
    mov val,#$42 
    ; Attempting arr1[noparse][[/noparse]arr2[noparse][[/noparse]i]] = val - arr1[noparse][[/noparse]arr2[noparse][[/noparse]2]] - arr1[noparse][[/noparse]3] in test = $3d 
    mov w,#arr2 
    ; requires a bank instruction here if i not 'already available'
    add w,i 
    mov fsr,w 
    mov w,#arr1 
    add w,ind 
    mov fsr,w 
    ; Job done - line below as a 'proof'
    mov ind,val
    


    As in Peter's post if Arr1 or Arr2 span banks it is a little uglier ....

    David
    ·
  • Peter VerkaikPeter Verkaik Posts: 3,956
    edited 2009-02-15 22:54
    David,

    In theory you can expand to any level of indirection,
    but that requires a change to the way sxb evaluates expressions.
    Currently, you can have only one operator per line as in
    ; Attempting arr1[noparse]/noparse]arr2[noparse][[/noparse]i = val - arr1[noparse]/noparse]arr2[noparse][[/noparse]2
    More complex expressions must be split over several lines.
    What jonnymac proposed, and me too, is·to allow
    an index at a fixed location, either a normal variable or an aliased
    array·variable. Then all that needs to change is the calculation
    of fsr. It requires no change on how expressions are evaluated.
    If the index is a normal variable, use·the current way·of calculating fsr,
    if the index is an array variable, use the proposed way·of calculating fsr.
    The remaining generated code would remain the same.

    regards peter
    ·
  • David BaylissDavid Bayliss Posts: 58
    edited 2009-02-15 23:36
    Well - my comment was really a multi-line comment on one line. The expression was

    arr1[noparse]/noparse]arr2[i = x

    and of course you are right - this is something not presently handled. I understand what you are proposing and I agree with your code and offered my simpler version for the easy case.

    Knowing just how high-level you want a high-level language to be is always hard....

    David [/i]
Sign In or Register to comment.