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.
|
|