I have a C
code in my mind which I want to implement in ARM
Programming Language.
The C code I have in my mind is something of this sort:
int a;
scanf("%d",&a);
if(a == 0 || a == 1){
a = 1;
}
else{
a = 2;
}
What I have tried:
//arm equivalent of taking input to reg r0
//check for first condition
cmp r0,#1
moveq r0,#1
//if false
movne r0,#2
//check for second condition
cmp r0,#0
moveq r0,#1
Is this the correct way of implementing it?
Your code is broken for a=0
- single step through it in your head, or in a debugger, to see what happens.
Given this specific condition, it's equivalent to (unsigned)a <= 1U
(because negative integer convert to huge unsigned values). You can do a single cmp and movls
/ movhi
. Compilers already spot this optimization; here's how to ask a compiler to make asm for you so you can learn the tricks clever humans programmed into them:
int foo(int a) {
if(a == 0 || a == 1){
a = 1;
}
else{
a = 2;
}
return a;
}
With ARM GCC10 -O3 -marm on the Godbolt compiler explorer:
foo:
cmp r0, #1
movls r0, #1
movhi r0, #2
bx lr
See How to remove "noise" from GCC/clang assembly output? for more about making functions that will have useful asm output. In this case, r0
is the first arg-passing register in the calling convention, and also the return-value register.
I also included another C version using if (a <= 1U)
to show that it compiles to the same asm. (1U
is an unsigned constant, so C integer promotion rules implicitly convert a
to unsigned
so the types match for the <=
operator. You don't need to explicitly do (unsigned)a <= 1U
.)
For a case like a==0 || a==3
that isn't a single range-check, you can predicate a 2nd cmp
. (Godbolt)
foo:
cmp r0, #3 # sets Z if a was 3
cmpne r0, #0 # leaves Z unmodified if it was already set, else sets it according to a == 0
moveq r0, #1
movne r0, #2
bx lr
You can similarly chain && like a==3 && b==4
, or for checks like a >= 3 && a <= 7
you can sub / cmp, using the same unsigned-compare trick as the 0 or 1 range check after sub maps a
values into the 0..n range. See the Godbolt link for that.