Tutorial 3: ARM assembly function call

Note

This is for practice, not for marks. Treat this as additional study material to help you develop your knowledge and skills on these topics. During the tutorial session, the TA will explain how to solve these problems.

Question 1: Understanding the stack

Report the final contents of the stack and the registers when the following ARM assembly instructions are executed. Assume that the initial stack is empty and R0=-1 R1=22 R2=3 R4=0.After that, rewrite the instructions using Pop/Push only.

STR R4, [SP, #-4]!
STR R4, [SP, #-4]!
STR R0, [SP, #-4]!
LDR R1, [SP], #4
STR R1, [SP, #-4]!
STR R2, [SP, #-4]!
LDR R0, [SP], #4

Question 2: Function call with no argument passed or value returned

Identify the caller, the callee and the instruction that the link register will have its address when the following program finishes execution.

.global _start

_start:

       MOV R0, #0
       MOV R1 #2
       ADD R1, R0, R1
       BL function_1
       LSR R3, #2
       AND R0, R1, R3
       .end

function_1:
       BX LR

Question 3: Function call with argument passed by value and a value returned

Convert the following C program into ARM assembly.

Note

To follow ARM calling convention: use R0–R3 for passing arguments, and use R0 for the return value. You can use the stack to pass the arguments if you want. Also Please make sure to follow the Callee-save convention (callee is responsible for leaving the registers as it found them)

int MAC (i1, i2, i3, i4);

void main(){

        int weight0 = 2;
        int    ifm0 = 18;
        int weight1 = 3;
        int    ifm1 = 8;
        int     ofm = MAC(weight0, ifm0, weight1, ifm1);
}

int MAC (i1, i2, i3, i4){
       return i1*i2 + i3*i4;
 }

Question 4: Passing arguments by reference vs passing by value

Given the following C program, what’s the result of each printf statement?

#include <stdio.h>

int ASR_Val (int i) {

       i = i >> 1;
       return i ;
}

void ASR_Ref (int *i) {

       *i = (*i) >> 1;
}

void main () {

       int w = 14;
       int w_returned ;

       w_returned = ASR_Val(w) ;
       printf("%d\n",w);
       printf("%d\n", w_returned);

       ASR_Ref(&w) ;
       printf("%d\n",w);

}

Question 5: Structs (Always passed by value)

Show, in ARM assembly, how to pass the struct in the following C program as an argument using the stack. Also, report the result of each printf statement.

#include <stdio.h>

struct Vec { //Vector struct that has two integers x and y.

       int x;
       int y;
};

struct Vec add2(struct Vec v);

void main(){

       struct Vec vector_to_pass;
       struct Vec vector_returned;

       vector_to_pass.x = 12;
       vector_to_pass.y = 43;

       vector_returned = add2(vector_to_pass);

       printf("%d\n",vector_to_pass.x);
       printf("%d\n",vector_to_pass.y);
       printf("%d\n",vector_returned.x);
       printf("%d\n",vector_returned.y);

}

struct Vec add2(struct Vec v){
//Function `add2`, that takes a struct of type `vec` and adds 2 to its integers and returns a struct of type Vec

       v.x = v.x + 2;
       v.y = v.y + 2;
       return v;
}

Question 6: Frame Pointer

Modify the previous program (Q5) to use the Frame Pointer FP (R11) with relative addressing to access arguments.

Note

Frame Pointer contains the base address of the function frame on the stack (Stack Pointer value right after entering a function). It is used to simplify addressing when passing arguments through the stack.

The following instructions will help you save and intialize FP properly.

start:
       ....
       BL add2

add2:
       PUSH {FP}
       ADD FP, SP, #4
       ....
       POP {FP}