Lab 3 - Assembly Implementation of C
| Name | ID |
|---|---|
| Mo'men Ahmed | 2200768 |
| John Sameh | 2200414 |
1. Introduction & Overview
This laboratory exercise involves compiling a C application to analyze the resulting compiler-generated assembly code and the linker-generated map file.
2. Learning Outcomes
- Compiling a C program
- Reviewing the assembly output listing and the map file.
3. Requirements
This lab utilizes the following environment:
- Software: KEIL µVision5 MDK IDE.
- Hardware: STM32 Nucleo-F401RE development board.
4. Procedure
-
Open the
CinAsmLabproject workspace. -
Ensure that the compiler is configured to generate assembly listings (
Options -> Listing -> C Compiler Listing) and is set to maximum optimization (Options -> C/C++ -> Optimization Level 3 (-O3)). -
Compile the source code, then review the output listing and map files to answer the questions below.
4.1 Assembly Code Listing
4.1.1 Evaluating the INIT_LIST Function
-
Q4: Which context is saved upon entry?
- Registers
r4,r5, andlrare preserved upon entering the function.
- Registers
-
Q5: Which instruction restores context and returns?
- The
POP {r4, r5, pc}instruction is responsible for restoring the saved context and returning execution from the subroutine.
- The
-
Q6: Which register acts as the loop counter
i?- Register
r0functions as the loop counter variablei.
- Register
-
Q7: How is the operation
i * 2000performed in assembly? * The instructionMOVS r2, #0x7dloads the decimal value 125 (0x7d) into registerr2(orr1depending on the exact build).-
Next,
LSLS r2, r2, #4shifts the register left by 4 bits, effectively multiplying it by 16, resulting in. -
Finally,
MULS r2, r0, r2multiplies the counteri(held inr0) by 2000, storing the final product back inr2.
-
-
Q8: How is the operand
offset[i]accessed in assembly?-
LDR r4, |L1.104|assignsr4the address of the.datasection. -
According to the map file, the
.datasection and theoffsetarray begin at0x2000_00d8, makingr4the base pointer. -
The array stores integers, which are each 4 bytes in length.
-
To determine the specific element's address, a calculation is needed.
-
LSLS r3, r0, #2shifts the indexi(inr0) left by 2 bits, effectively multiplying it by 4 to account for the integer byte size. -
The exact address is the base address (in
r4) plus 4 times the index (inr3). -
LDR r5, [r4,r3]retrieves the value at this calculated memory location intor5, representing the value ofoffset[i].
-
4.1.2 Evaluating the FIND_IN_LIST Function
-
Q9: Which context is saved upon entry?
- No context is preserved when entering this function.
-
Q10: Which instruction returns from the subroutine, and why is it different?
-
The function uses
BX lrto return. -
This differs from
init_listbecause no context was pushed to the stack, so nothing needs to be popped off.
-
-
Q11: Which register holds the
keyargument?- Register
r0contains thekeyargument.
- Register
-
Q12: How is the loop repeat test performed?
4.2 Map File
4.2.1 Default Program
- Q13: Image Symbol Table (Global Symbols)
| Symbol | Starting Address | Size |
|---|---|---|
$Super$$main |
0x0000_0851 |
26 |
list_init |
0x0000_0809 |
46 |
list_find |
0x0000_0837 |
26 |
list |
0x2000_0100 |
40 |
offset |
0x2000_00d8 |
40 |
-
Q14: Memory Map for
main.o-
.text: Size0x6cbytes, Type: Code, Attributes: Read-only. -
.data: Size0x28bytes, Type: Data, Attributes: Read-write. -
.bss: Size0x28bytes, Type: Zero, Attributes: Read-write.
-
-
Q15: STACK Size
-
The stack size is
0x0400bytes, which equals 1024 bytes. -
Yes, this aligns with the memory layout file declaration:
ARM_LIB_STACK (0x20000000+4096) EMPTY - 0x0400.
-
-
Q16: Image Component Sizes for
main.o
| Configuration | Code | data | RO Data | RW Data | ZI Data | Debug |
|---|---|---|---|---|---|---|
| non-const offset | 108 | 10 | 0 | 40 | 40 | 1535 |
4.2.2 Specifying C Data as Read-Only to Save RAM
Change the C source code to declare the offset array as const, then rebuild.
- Q17: Updated Image Symbol Table
| Symbol | Starting Address | Size |
|---|---|---|
$Super$$main |
0x0000_0851 |
26 |
list_init |
0x0000_0809 |
46 |
list_find |
0x0000_0837 |
26 |
list |
0x2000_00d8 |
40 |
offset |
0x0000_0a84 |
40 |
-
What changed and why?
-
The
offsetarray shifted from RAM (0x2000_00d8) to ROM (0x0000_0a84). -
Consequently,
listmoved to the first position in RAM (0x2000_00d8), as it no longer follows theoffsetarray.
-
-
Q18: Changes in
main.txt- The
offsetarray is relocated to.constdatainstead of.data, represented by the assembly directive:AREA ||.constdata||, DATA, READONLY, ALIGN=2.
- The
-
Q19: Updated Memory Map for
main.o-
.text:0x6cbytes, Code, Read-only. -
.constdata:0x28bytes, Data, Read-only. -
.bss:0x28bytes, Zero, Read-write.
-
-
Q20: Updated Image Component Sizes
| Configuration | Code | data | RO Data | RW Data | ZI Data | Debug |
|---|---|---|---|---|---|---|
| const offset | 108 | 10 | 40 | 0 | 40 | 1539 |
-
What changed and why?
-
By declaring
offsetasconst, the module requires 40 bytes of Read-Only (RO) data instead of Read-Write (RW) data. -
This technique successfully minimizes RAM requirements.
-
Because microcontrollers typically possess significantly more Flash ROM capacity than RAM, this is a highly valuable optimization.
-