Assembly Language Programming(1) Start
π» Emulator for ARM programming
I use ARMv7 DE1-SoC.
Register
This register is a 32-bit register (8 hexadecimal digits, 32-bit).
Each 0 represents a hexadecimal digit. And each hexadecimal digit holds 4 bits of data. (4bit*8=32bit)
(1) R0~R7 Registers
In ARMv7 (32-bit architecture), R0 to R7 are general-purpose registers (GPRs).
They can be used freely, but by convention, they often serve specific purposes.
β Overview of R0~R7 (ARMv7, 32-bit)
Register | Description |
R0 | First function argument (Argument 1) |
R1 | Second function argument (Argument 2) |
R2 | Third function argument (Argument 3) |
R3 | Fourth function argument (Argument 4) |
R4 | Callee-saved register (must be preserved across function calls) |
R5 | Callee-saved register (must be preserved across function calls) |
R6 | Callee-saved register (must be preserved across function calls) |
R7 | Callee-saved register OR System Call Number (Syscall Number) |
β Detailed Explanation
R0~R3 (Argument & Return Registers)
Used for passing function arguments.
The return value of a function is stored in R0.
If a function has more than four arguments, the extra arguments are passed via the stack.
Example (ARM Assembly)
MOV R0, #5 ; First argument = 5
MOV R1, #10 ; Second argument = 10
BL add_numbers ; Call add_numbers function
MOV R4, R0 ; Store return value from R0 into R4
R4~R7 (Callee-Saved Registers)
These registers must retain their values across function calls.
If a function modifies R4~R7, it must restore them before returning.
Often used for loop counters or temporary storage.
Example (Using PUSH/POP for Preservation)
PUSH {R4, R5, R6, R7} ; Save R4~R7 before modifying
MOV R4, #20 ; Modify R4
MOV R5, #30 ; Modify R5
POP {R4, R5, R6, R7} ; Restore original values before returning
R7 (Syscall Number Register)
In Linux system calls, R7 holds the system call number.
Used with the
SVC
(Supervisor Call) instruction to request a system service.
Example (Linux Syscall: exit(0))
MOV R7, #1 ; sys_exit (System call number 1)
MOV R0, #0 ; Exit code 0
SVC #0 ; Execute system call
β Summary
R0~R3: Used for passing function arguments and storing return values.
R4~R7: Callee-saved registers (must be preserved across function calls).
R7: Also used for syscall numbers when making system calls.
If a function modifies R4~R7, it must restore them before returning.
(2) SP, LR, PC Register
1. SP (Stack Pointer)
Register Name:
R13
Purpose: Points to the top of the stack.
Description:
Manages the memory location for local variables and register backup during function calls.
The stack typically grows downward (Descending Stack), so PUSH decreases SP, and POP increases SP.
Example (PUSH/POP operations)
PUSH {R4, R5, R6} ; Save R4~R6 to stack (SP decreases)
POP {R4, R5, R6} ; Restore R4~R6 from stack (SP increases)
2. LR (Link Register)
Register Name:
R14
Purpose: Stores the return address before calling a function.
Description:
The BL (Branch and Link) instruction saves the current PC (Program Counter) value to LR before jumping to a function.
At the end of the function, LR is restored to PC to return to the caller.
Example (Function Call and Return)
BL my_function ; Call my_function, store PC in LR
...
my_function:
MOV R0, #10 ; Function execution
MOV PC, LR ; Return to caller
3. PC (Program Counter)
Register Name:
R15
Purpose: Stores the address of the currently executing instruction.
Description:
Modifying PC changes the programβs execution flow (e.g., branching, jumping).
PC increments by +4 (4 bytes) per instruction in 32-bit ARM.
Used for function calls, loops, conditional statements, and exception handling.
Example (PC Manipulation - Jump to Label)
B my_label ; Jump to my_label (PC changes)
...
my_label:
MOV R0, #5
β Summary
Register | Description |
SP (R13) | Points to the top of the stack, manages function call stack. |
LR (R14) | Stores the return address for function calls. |
PC (R15) | Holds the current instruction address, controls program flow. |
ARMv7 uses SP for stack management, LR for function returns, and PC for program execution control.
Understanding these registers is essential for function calls, stack operations, and branching.
(3) CPSR & SPSR Registers
1. CPSR (Current Program Status Register)
Purpose: Stores and controls the current processor state.
Contains: Flags, interrupt settings, and processor mode information.
Description:
Condition flags:
N
,Z
,C
,V
store arithmetic results.Interrupt control: Disables/enables IRQ and FIQ interrupts.
Processor mode: Indicates current execution mode (User, System, etc.).
β CPSR Structure (32-bit)
Bit | Field | Description |
31 | N (Negative) | Set if result is negative |
30 | Z (Zero) | Set if result is zero |
29 | C (Carry) | Set if carry occurred |
28 | V (Overflow) | Set if overflow occurred |
27-8 | Reserved | Unused |
7 | I (IRQ Disable) | 1 = Disable IRQ interrupts |
6 | F (FIQ Disable) | 1 = Disable FIQ interrupts |
5 | T (Thumb Mode) | 1 = Enable Thumb mode |
4-0 | Mode | Indicates processor mode (User, System, etc.) |
β CPSR Example
MRS R0, CPSR ; Read CPSR into R0
ORR R0, R0, #0x80 ; Disable IRQ (Set I bit)
MSR CPSR_c, R0 ; Write back to CPSR
This disables IRQ interrupts by modifying the CPSR register.
2. SPSR (Saved Program Status Register)
Purpose: Stores the previous CPSR value during exceptions or interrupts.
Description:
When an exception occurs, the current CPSR is saved into SPSR.
This allows the system to restore the original state after handling the exception.
Used only in privileged modes (Supervisor, FIQ, IRQ, Abort, Undefined).
β SPSR Example
MRS R0, SPSR ; Read SPSR into R0
MSR SPSR_c, R1 ; Write R1 value to SPSR
This reads and modifies the SPSR register.
β CPSR vs SPSR Comparison
Register | Purpose |
CPSR | Stores the current program status |
SPSR | Stores CPSR during exceptions to restore later |
CPSR is used for managing the current execution state.
SPSR is used for saving/restoring processor state during exceptions.
β Summary
CPSR controls the processor's state, while SPSR helps store the CPSR value when an exception occurs.
SPSR is mainly used in privileged execution modes.
Program
Code Explanation (ARM Assembly)
global _start ; Declare _start as a global symbol (Entry Point)
_start: ; Define the program's starting label
MOV R0, #30 ; Store 30 in R0 (Exit Code)
MOV R7, #1 ; Store 1 in R7 (sys_exit system call)
SWI 0 ; Execute software interrupt (System call execution)
β Explanation
.global _start
- Declares
_start
as a global symbol, making it the entry point of the program.
- Declares
_start:
- A label marking the beginning of program execution.
MOV R0, #30
Stores
30
in register R0.In Linux system calls, R0 holds the exit code when calling
sys_exit
.This means the program will terminate with an exit status of
30
.
MOV R7, #1
Stores
1
in register R7.In ARM Linux, system call numbers are stored in R7.
1
corresponds to thesys_exit
system call, preparing the program for termination.
SWI 0
(Software Interrupt, Supervisor Call)Executes a software interrupt (SWI) to request a system call from the kernel.
Since R7 = 1 (sys_exit), the program will terminate.
β Program Execution Summary
Execution starts at
_start
.Sets exit code (30) in R0.
Prepares sys_exit system call (1) in R7.
Triggers the system call using SWI 0 β Program terminates.
Thus, this program executes and immediately exits with an exit code of 30.