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.
Bookmarks