I have just started to learn about how arrays are stored in registers and I am very confused by how pointers work.
Suppose the pointer Z points to the following character array in memory, which is at address 0xABCD
:
['1', '3', '2']
Given the following snippet:
ld r23, Z+
ld r24, Z
What is the value of r24
after the code executes?
Would Z be index 0? Or would it be the value at index 0 which is 1, or does it have something to do with the address 0xABCD
?
Please be nice. I really want to learn this stuff, my teacher is not the best at explaining. Any help would be greatly appreciated!
There are three pointer registers: X - which is actually pair of registers r27:r26, Y - r29:r28 and Z - r31:r30
And there are four different models of indirect access to read/write the memory using that pointers:
1) Plain indirect access:
ld r16, X
st Y, r16
is used just to load and store the data from/to the address pointed by those registers.
2) Indirect access with post-increment:
ld r16, X+
st Z+, r16
Those operations do write and read using the address currently stored in the pointer registers. After those operations, the value stored in the corresponding register's pair is increased by one.
3) Indirect access with pre-decrement:
ld r16, -Y
st -X, r16
Those operations firstly decrease by one the value stored in the corresponding register's pair, and then do read/write from/to the new computed address.
4) Indirect access with displacement (for Y and Z only):
ldd r16, Y+1
std Z+30, r16
Those are do not change the value stored in the pointer register, but do read and write memory using address specified by the pointer register PLUS the given offset. Offset is always positive between 0 and 63 (inclusive).
There is no ldd
and std
for X register.
Note. On devices with 256 bytes and less of addressable data space, only low byte of the pointer register pairs are used and post-increment and pre-decrement also do not modify them. While on devices which able to address more than 64KB, there are also additional I/O registers (RAMPX, RAMPY, RAMPZ) are used to obtain the higher bits of the address. When using with post-increment or pre-decrement, those registers are also updated.
Also note, when using pre-decrement or post-increment to store the data contained in the one of the pointer pair's registers, e.g.:
st X+, r26 // r26 is a part of X register
st -Y, r29 // r29 is a part of Y register
etc.
then result of such operations is undefined.
So, answering your question:
If Z points to the first byte of the char array, then operation ld r23, Z+
will load the first byte value into r23 and increase value of Z (i.e. registers r31:r30) by one after that. So, the Z will point at the second byte of the array.
Then, next operation ld r24, Z
will load the second byte into r24 and the Z pointer will remain unchanged.