Reputation: 61
I'm learning ARM assembly, using Keil uVision IDE to simulate on intel-windows system.
I'm trying to store a data in a register to the memory with using STR R5, [R12]
.
the values are generated before, and stored correctly until the value in R5 hits 377. (The value before 377 is 233.) I assume this is a problem caused by the size of the value in binary.
Since 233 = 1110 1001 and 377 = 0001 0111 1001. value is passing over the 8-bits.
Here is the part of the code that I think is problematic:
LDR R6, [R3],#1 ; loads data from memory to R6
LDR R7, [R4],#1 ; loads data from memory to R7
ADD R5, R6, R7 ; adds them (in this case its 144+233=377)
STR R5, [R12],#1; stores the value '377' to the memory.
The value in the memory pane looks like this:
instead of 377, its 121.
I've added a breakpoint and observed the value of R5 in debug mode, its correctly holding 377 in R5. So; the problem is to write that 377.
Any ideas why this happens and how can I solve this problem?
Thanks.
Upvotes: 0
Views: 762
Reputation: 26646
37710 doesn't fit in 8 bits. Truncated to 8 bits, as if subtracting 256, the value becomes 0111 1001, which is 12110.
Since you're using loads and stores of 4 byte entities, but working with bytes, I believe that you're getting more data in the registers than you expect. Hence the values past 121, namely, 098 & 219...
All modern hardware is what we call byte addressable.
On a byte addressable machine, each byte has its own address. So, when you store a 4 byte integer, it takes 4 bytes, and since it takes 4 bytes, it also takes 4 addresses!
If you choose to, you can look at the individual bytes, but that's not the big picture. Taken alone and individually, each byte of the 4 doesn't represent the 4 byte value, but all together the 4 bytes do.
When you store a 4 byte integer, you must allow it 4 byte addresses. So, if one 4-byte integer is located at 0x20000400, then the next available address for storing anything else is 0x20000404, because 0x20000400-0x20000403 are in use storing that 4 byte integer.
If you choose to store a 4 byte integer at location 0x20000401, that will overwrite the memory used by the former 4 byte integer stored at 0x20000400.
Suggest you avoid all complex addressing modes so you can see in the register the exact effective address.
So, instead of doing LDR R6, [R3],#1
, if you really want to use offset of +1, then do ADD R6,R3,#1
followed by LDR R6,[R6]
. This will simplify your debugging.
But you probably shouldn't be using an offset of +1 anyway, since we now understand that 4-byte integers take 4 addresses. Offsets of +0 and +4 make sense here, not +1.
Upvotes: 3