I am new in ARM and assembler. I tried to write a simple program to store value from register to memory.
string:
.ascii "%d\012\000"
.align 2
var1:
.word 0
.align 4
.text
.global main
main:
push {ip, lr}
ldr r1, adr_var1
ldrb r1, [r1]
mov r1, #370
uxtb r3, r1
ldr r1, adr_var1
strb r3, [r1]
ldr r0, adr_string
mov r1, r3
bl printf
mov r1, #0
mov r7, #1
pop {ip, pc}
adr_var1:
.word var1
adr_string:
.word string
The problem occurs when writing data to memory. When it tries to write the value 370 (hex: 0x172), only 0x72 is saved. STR seems to only transfer 8 data bits. I have tried different configurations with the STR instruction (e.g. STRB) and nothing works. My question is how can store this value to memory.
Thank you for any help and answer.
strb r3, [r1]
is a byte store. Of course it only stores one byte.
uxtb r3, r1
zero-extends a byte into a register so a str r3, [r1]
word store would store 4 bytes, with the high 3 bytes all zeros. Try it with the initial value in memory being 0xFFFFFFFF
so you can see the difference between storing a byte and storing a zero-extended word.
If you want to store the full 370
, simply don't truncate it to 8 bits before storing!
Also, you should put your .align
before the var1:
label (and the .word 0
). .align
expands to padding at its location; If you want var1
to be aligned so you have to get to an alignment boundary first.
Also, use a debugger to examine registers and memory as you single step. It would have been obvious that your 370
got truncated to (uint8_t)370
by uxtb
(unsigned extend byte).
Plus, your code doesn't print the word from memory, it only passes r3
to printf. So you couldn't see the difference between a byte store leaving upper bytes unmodified vs. a word store with that buggy debug-print. Using a debugger is vastly better.