CingirakliDumbelek
CingirakliDumbelek

Reputation: 61

Cannot store data correctly in memory on ARM Assembly

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: The memory of the program

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

Answers (1)

Erik Eidt
Erik Eidt

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

Related Questions