Converting C Conditionals to ARM Assembly
In this post we can explore how to the gcc
compiler converts to C to ARM assembly language. We’ll specifically look at conditional logic. We’ll look at examples of if
statements, if
statements with else if
and else
, then end with a switch
statement. To convert C to ARM assembly we will use the -S
flag on GCC. All these examples were done on a Raspberry Pi running Raspbian.
Converting an if statement from C to Assembly
As simple as it can get. Here we have a 32-bit ARM Architecture making an int
32-bits and the register width is also 32-bits
. Let’s create a simple if
conditional statement in C and we’ll convert it to assembly.
// file if.c
int
main(int argc, char *argv[])
{
int a,b,x;
a = 1;
b = 2;
x = 3;
if(a == b)
{
x = 4;
}
return x;
}
Pseudo Logic of if statement in assembly
When we have following conditional logic in C:
if ( a == b )
x = 4;
It will have the following pseudo logic in assembly. Hopefully you follow this strange mix of assembly and logic I created on the fly.
cmp r2, r3 ; r2 = value of a, r3 = value of b
bne BEYONDIF ; the branch is the opposite of ==
mov r3, #4 ; the statements inside the if when true
str r3, [address of x] ; put 4 into x
BEYONDIF:
The BEYONDIF
label represents code outside the if
statement and allows us to jump out when the if condition doesn’t hold.
ARM Assembly of our if statement
Below is the ARM assembly from the C code above. We want to focus on where the variables are set, and especially where we have the if
statements and variable a
is compared to variable b
. This is done by simply running gcc -O0 -Wall -S if.c
. The -O0
is crucial since it’s turns optimization off. However, to the trained eye you can spot some places the ARM assembly code is not optimal.
When looking at the assembly the stack pointer and frame pointer are a large part of any program. Hopefully, in another post I’ll go over the stack and frame in detail. Divert your eyes and try to focus on the meat of the main
C function, which is the conditional logic we created. This starts on line 10 of the assembly.
|
|
Converting an if statement with if-else and else from C to Assembly
Alright, now let’s do a little more with an if
and add two if-else
blocks, as well as, an else
condition.
// file: ifelse.c
int
main(int argc, char *argv[])
{
int a,b,x;
a = 1;
b = 2;
x = 3;
if(a == b)
{
x = 4;
}
else if(a > b)
{
x = 5;
}
else if (a < b)
{
x = 6;
}
else
{
x = 7;
}
return x;
}
Pseudo Logic of if statement in assembly
When we have the following conditional logic in C:
if ( a == b )
x = 4;
else if (a > b)
x = 5;
else if (a < b)
x = 6;
else
x = 7;
It will have the following pseudo logic in assembly.
AEQB: ; if (a == b)
cmp a, b
bne AGTB ; the branch is the opposite of ==
str 4, [address of x]
b GETOUT
AGTB: ; if (a > b)
cmp a, b
ble ALTB
str 5, [address of x]
b GETOUT
ALTB: ; if (a < b)
cmp a, b
bgt ELSE
str 6, [address of x]
b GETOUT
ELSE: ; else statement
str 7, [address of x]d
GETOUT:
The GETOUT
label represents code outside the if
statement, after the else
.
Assembly of if statement with else-if and if from our C Example
Now let’s see what an if
looks like in ARM assembly when we have two else if
blocks and an else
statement.
|
|
Converting a switch statement in C to assembly
Now that we’ve seen how if
statements convert from C to assembly, let’s look at the switch
statement in C.
// file: switch.c
int
main(int argc, char *argv[])
{
int x,y;
x = 1;
switch(x)
{
case 0:
y = 10;
break;
case 1:
y = 11;
break;
default:
y = 13;
}
return y;
}
Pseudo Code of the switch statement in Assembly
If we have the following C switch
statement:
switch(x)
{
case 0:
y = 10;
break;
case 1:
y = 11;
default:
y = 13;
}
This is the equivalent to this in C:
if ( x == 0)
y = 10;
if ( x == 1)
y = 11;
else
y = 13;
From here our “pseudo-assembly” would be:
cmp a,#0
beq CASE0
cmp a,#1
beq CASE1
b DEFAULT
CASE1:
str 10, [address of y]
b OUTSIDECASE
CASE2:
str 11, [address of y]
b OUTSIDECASE
DEFAULT:
str 11, [address of y]
OUTSIDECASE:
Assembly Language of a C switch statement
Let’s look now how a switch
statement in C is converted to assembly language.
|
|