I am a beginner tinkering with ARM7 Assembly Language programming and have been stuck on this one issue.
I am trying to implement a function in C that takes two unsigned 32 bit vars (uint32_t A and uint32_t B), adds them together and then returns a uint64_t value where the sum contains the carry.
I have included both my C code and ARM7 Assembly Language code below. However, my code doesn't output the correct value; which is probably due to my ASM instructions. Also, I am running Linux with a 32 bit machine.
addVal.s (code below)
.global addVal
.text
addVal:
ADD R0, R0, R1
ADC R0, R1
BX LR
addVal.c (code below)
#include <stdio.h>
#include <stdint.h>
extern uint64_t addVal(uint32_t x, uint32_t y);
int main()
{
uint32_t a, b;
uint64_t c;
a = 4000000000;
b = 1000000000;
c = addVal(a,b);
printf("a = %u\r\n", a);
printf("b = %u\r\n", b);
printf("c = a + b = %llu\r\n", c);
return 0;
}
compiled on command line using
as -o addVal addVal.o addVal.s
gcc -o addVal addVal_s.o addVal.c
./addVal
ADC R0, R1
is wrong.
As uint64_t
exceeds the size of a single register, it's spread into a subsequent range of registers. The low word resides in R0
, high word in R1
. So the target register for ADC
needs to be R1
.
Second problem is that you don't want to add the original low word of R1
into the result high word, but only the carry bit. So you can just clear R1
first.
.text
.arm
.global addVal
.func addVal
addVal:
ADDS R0, R0, R1
MOV R1, #0
ADC R1, R1, #0
BX LR
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With