2 bytes to word array variable - fastest way


Results 1 to 16 of 16

Threaded View

  1. #8
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,621


    Did you find this post helpful? Yes | No

    Default Re: 2 bytes to word array variable - fastest way

    Actually I may have messed that up myself, based on this post I'm not sure it'll do what the OP wanted - to be honest.

    I agree it's a abit unituitive and I'll admit I haven't sat down and looked into what's really happening - until now. Before I go on I'll point out that I suck at ASM so if this is completely wrong then I applogise before hand and hope that whoever knows/understands better will correct me.

    When you declare an array of words PBP 'calculates' the start adress of that array in memory (where in the RAM memory the first byte in the array is located). If, somewhere in your program, you use the LOWBYTE,HIGHBYTE "modifiers" it also calculates where the lowbyte and highbyte of the first word in the array is. Glancing at the .lst file it might look something like this:
    Code:
    '00038 _myArray                        EQU     RAM_START + 01Dh
    '00043 _myArray??LOWBYTE               EQU     _myArray
    '00044 _myArray??HIGHBYTE              EQU     _myArray + 001h
    So all it really knows (and need to know) is where myArray starts. The .LOWBYTE of myArray is at the very same adress as the array starts and .HIGHBYTE is at the next adress. Makes sense.

    Now, let's say we do something like this:
    Code:
    myArray VAR WORD[3]
    myByte VAR BYTE
     
    myVar = myArray[0]
    myVar = myArray[1]
    What's going on here then? We're actually trying to stuff a WORD from the array into our BYTE-sized variable. The code generated looks like this:
    Code:
    movff   _myArray, _myVAR
    movff   _myArray + 00002h, _myVAR
    First it takes the byte at the start adress of the array (which is the low byte of word 0, right) and puts that in our BYTE-variable. Then it takes start-adress of the array, adds 2 to that adress and grabs the byte at that location. This is the third byte in our WORD-array so it's grabbing the low byte of word 1. This is pretty straight forward and intuitive - it simply truncates the word from the array into our byte variable.

    Now,
    Code:
    myVar = myArray.LowByte
    myVar = myArray.HighByte
    The above PBP code compiles:
    Code:
    movff _myArray??LOWBYTE, _myVAR
    movff _myArray??HIGHBYTE, _myVAR
    As we saw above myArray??LOWBYTE is the very same adress as the start of the array so this IS the low byte of the first word. myArray??HIGHBYTE is at the start adress of the array + 1 so we'll get the high byte of the first word. Still OK, what we wanted, and probably what we expected.

    Now lets start indexing into the array.
    Code:
    myVar = myArray.LowByte[0]
    myVar = myArray.HighByte[0]
    This code compiles to:
    Code:
    movff   ((_myArray??LOWBYTE) + (000h)), _myVAR
    movff   ((_myArray??HIGHBYTE) + (000h)), _myVAR
    As you can see this takes the adress of the lowbyte of the first word in the array, adds nothing (zero) to it, gets the byte at that adress and puts it in our byte variable. Then it takes the address of the highbyte of the first word in the array, adds nothing to that and gets the byte at that adress. This is still fine, what we wanted (perhaps) and what we might expect. But now it starts to get interesting.

    Code:
    myVar = myArray.LowByte[1]
    myVar = myArray.HighByte[1]
    From this we might, intuitively, expect to get the low and high byte of the second word the array but the above code compiles to:
    Code:
    movff   ((_myArray??LOWBYTE) + (001h)), _myVAR
    movff   ((_myArray??HIGHBYTE) + (001h)), _myVAR
    So, what's going on here... It takes the adress of the 'lowbyte' (the very first byte in our array, low byte of word 0), adds one to that address and gets the byte at that adress. What we're getting is actually the second byte in the array which is the high byte of the first word (word 0). Then it takes the adress of 'highbyte', adds one to that and gets the byte at that adress which is now the third byte in the array or the low byte of the second word (word 1). Not what one might expect but when you know what goes on under the hood it kind of makes sense.

    And, to illustrate it one more time:
    Code:
    MyVar = myArray.Lowbyte[2]
    myVar = myArray.HighByte[2]
    Intuitively we'd expect to get the low and high byte of the third word but we now know that ain't what's happening because we're telling it to index an array of words byte by byte. We tell it to get the byte at the adress of myArray.Lowbyte+2. myArray.Lowbyte is the very first byte in the array, add two to that and we'll end up the adress of the third byte in the array which is the low byte of word 1 - not word 2 as we intutively might think. And, obviously the same thing happends with myArray.HighByte[2] - it gets 4th byte in the array which is the high byte if word 1.

    What we need to do when working with word-arrays on a byte-by-byte-basis is to index, or step, thru them in steps of 2. Like....
    Code:
    accData VAR WORD[16]
    Index VAR BYTE
     
    For Index = 0 to 16 STEP 2
      accData[Index] = ADRESL 'Low byte  (bytes 0, 2, 4, 6...)
      accData[Index+1] = ADRESH  'High byte  (bytes 1, 3, 5, 7...)
    NEXT
    So, again, I'm not sure my earlier advice is actually going to work. It might work if the word indexed is first but it kind of screws up as we've seen above.

    /Henrik.
    Last edited by HenrikOlsson; - 8th June 2011 at 19:03.

Members who have read this thread : 0

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts