Lecture 19 - C and Assembly

Published

March 30, 2026

Goals

  • Get introduced to C
  • See the compiling process in action and see what generated assembly looks like
  • Revisit the while vs for in compiled code
  • Start looking at how C handles data

source code

C

Let’s take our first real look at C

I have been sneaking C past you for a couple of class periods at least.

The truth is, C looks quite a bit like Java. To be more accurate, Java looks quite a bit like C. C, however, lacks object oriented structures, while Java expects everything to be an object.


/*
 * variables.c
 */

int main(int argc, char *argv[])
{
    int x, y, z;

    x = 42;
    y = 19;

    z = x + y;
}

C is a block oriented language, that, like Java uses curly braces to indicate blocks

The language is typed, so we need to declare our variables with types.

Like Java, there is a function called main which serves as the entry point to the program

Java

public static void main(String[] args)

C

int main(int argc, char *argv[])

In both cases, the function is receiving a list of the arguments passed to the program on the command line. Shortly you will be able to read the C version and understand it.

expressions look the same as they do in Java, complete with the semi-colon at the end.

Even comments are the same.

Compiling

To compile the program, we are going to use a special version of gcc that can produce code for ARM ISAs.

$ arm-none-eabi-gcc -S variables.c

The -S flag says that we would like this to just compile and not include an assemble step as well

Now we can look at the assembly file. You can ignore everything that starts with a . – those are just directives for the assembler.

fp and sp are are just different names for registers in our register file – r11 and r13 We will talk about their purposes shortly

The first few lines of actual assembly we will ignore for the moment as well until we get to:

mov r3, #42
str r3, [fp, #-8]
mov r3, #19
str r3, [fp, #-12]
ldr r2, [fp, #-8]
ldr r3, [fp, #-12]
add r3, r2, r3
str r3, [fp, #-16]

Pay particular attention to how we store immediate values into r3 and then store them into memory

So, when I said that the registers were basically our variables, this is a partial truth. Our variables are actually being stored in memory. When we want to use them, we have to fetch them back out again.

So, it appears that x is stored at [fp - 8] , y is at [fp - 12] and z is at [fp - 16]

We are going to see this pattern a lot with RISC architectures. We don’t have instructions that can operate on values in memory, so we are going to see the “load the value”, “do a thing”, “store the result” pattern fairly often.

What does this tell you about variable names? They are no longer present! Variable names are purely for our benefit. The compiler only cares that they are unique strings, and it abandons them as soon as the file is parsed. So, don’t be stingy with them – they are there to make your programs easier to read

while v. for

Now we are ready to return to the while/ for showdown.

We can start by taking a look at the two C files to remind ourselves what these loops are doing.

Let’s compile while.c and take a look.

Here is the code that is relevant to us


    mov r3, #20
    str r3, [fp, #-16]
    mov r3, #0
    str r3, [fp, #-8]
    mov r3, #0
    str r3, [fp, #-12]
    b   .L2
.L3:
    ldr r2, [fp, #-8]
    ldr r3, [fp, #-12]
    add r3, r2, r3
    str r3, [fp, #-8]
    ldr r3, [fp, #-12]
    add r3, r3, #1
    str r3, [fp, #-12]
.L2:
    ldr r2, [fp, #-12]
    ldr r3, [fp, #-16]
    cmp r2, r3
    blt .L3

There are a couple of things to note in here.

Our branches are to labeled lines in the code instead of being relative offsets

More importantly, there is even more movement back and forth to memory

What are the locations for count, sum and i?

Let’s look at our for loop:

Okay, let’s look at the compiled for-loop


    mov r3, #20
    str r3, [fp, #-16]
    mov r3, #0
    str r3, [fp, #-8]
    mov r3, #0
    str r3, [fp, #-12]
    b   .L2
.L3:
    ldr r2, [fp, #-8]
    ldr r3, [fp, #-12]
    add r3, r2, r3
    str r3, [fp, #-8]
    ldr r3, [fp, #-12]
    add r3, r3, #1
    str r3, [fp, #-12]
.L2:
    ldr r2, [fp, #-12]
    ldr r3, [fp, #-16]
    cmp r2, r3
    blt .L3

Look at that – it compiled to the same code! We can label this confirmed.

Mechanical level

vocabulary

Skills