ARM Assembly - Adding two Registers

I'm trying to add two registers together in ARM Assembly, by dereferencing the first two registers, and then storing the result in the third register. At the moment I have 3 variables & a function, which are as follows;

extern void my_function(int* x, int* y, int* total); int main(void) < int x = 1; //R0 int y = 2; //R1 int total = 0; //R2 while(1)< my_function(&x, &y, &total); printf("\x1b[5;5HTotal = %d, total"); >> 

And a function this does the following With the first two registers, I'm trying to dereference them, add them together and store the result in a third register. This is my assembly code;

ldr r4, [r0] @ Dereference r0, and store the address in R4 ldr r4, [r1] @ Dereference r1, and store the address in R4 add r2, r0, r1 @ Add r0 & r1 together, and store in R2 str r4, [r2] @ Store r2 address in r4 

When I print this out, the answer is 0. My question is, when I do the first two lines in assembly, does ldr r4, [r0] get replaced with ldr r4, [r1] which is causing the output to be 0? Do they each need to be stored in their own register? Or am I just basically printing out the total (r2)?

asked Feb 9, 2020 at 16:35 93 1 1 gold badge 2 2 silver badges 16 16 bronze badges "When I print this out" - what exactly are you printing? total ? r4 ? Commented Feb 9, 2020 at 16:38

first off are r0, r1 and r2 pointers to the variable (int *x, int *y . ) or do they contain the value themselves? [r0] is indirect r0 is not add r2,r0,r1 will add the two together and put the result in the third if they are not the address to the value but are the value

Commented Feb 9, 2020 at 16:38 @ForceBru, I'm trying to print out the total variable. Commented Feb 9, 2020 at 16:39

read the arm documentation please ldr r4,[r0] means use the value in r0 as an address read the 32 bit value in memory at that address and put it in r4. then ldr r4,[r1] does the same thing but uses the contents of r1 as the address and r4 is now overwritten with the new value losing whatever you did in the ldr r4,[r0]. if r0 and r1 are addresses then add r2,r0,r1 is just adding addresses/pointers not values. and str r4,[r2] now puts r4 which you read from the address of r1 into the address of r0,r1, there have been no data values used at this point

Commented Feb 9, 2020 at 16:40 nothing about your code will do that your code is doing *(&x + &y) = *y; Commented Feb 9, 2020 at 16:43

1 Answer 1

Never start an assembly language project without the documentation. Then actually read that documentation.

You have a C compiler so you can just see what it does and then figure out what each instruction is doing and then figure out where you went wrong.

void my_function(int* x, int* y, int* total)

can produce depending on command line options

my_function: ldr r3, [r0] ldr r1, [r1] add r3, r3, r1 str r3, [r2] bx lr 

you also have to understand the calling convention for the compiler you are using to make the C/asm transition. for this case in arm r0 is the address of x, r1 the address of y, and r2 the address of total.

ldr r4, [r0] @ read the value of x into r4 ldr r4, [r1] @ read the value of y into r4 losing/discarding the value of x add r2, r0, r1 @ add the pointers together destroying the pointer to total str r4, [r2] @ store the value of y into a location destroying whatever was there 

per the typical calling convention (a compiler can choose to use/create whatever they want so you need to know the convention) for arm r4 is volatile so you need to push it on the stack, you cant destroy what is in it during your function.

because your program does not modify the total variable and it is part of .bss the bootstrap has zeroed total to zero, and you are simply printing out that value, that is why you see zero your code has nothing to do with it. The odds of the address of x plus the address of y being the address of total is very very small, basically zero (yet a program could be crafted where it works), so again your code has nothing to do with the zero value in total.