Inside a Function Call: Registers, Stack, and Assembly Explained
This article systematically analyzes a function call in an embedded system from four perspectives—assembly code, registers, stack layout, and map files—illustrating how the compiler generates the call, what values each register holds, how the stack is allocated, and how to trace execution using disassembly and memory views.
Overview
The article provides a systematic analysis of a function call in an embedded system, examining it from four angles: assembly instructions, register contents, stack layout, and map files. It demonstrates what the compiler does when generating the call and how to trace the execution step by step.
Environment Description
The examined function flow is:
Serial port receives a command.
An interrupt invokes the interface uint16_t getUartData(void). getUartData calls shell_cmd_parse; the article follows the execution from the point where shell_cmd_parse is entered.
Breakpoint and Register Analysis
At breakpoint line 2800, the register state is examined:
R0‑R12 : Values are undefined because getUartData may be called from any function in a multi‑process scenario.
SP : Current stack pointer, e.g., 0x20008948.
LR : Return address to the caller of getUartData; the map file shows that after getUartData finishes it returns to parseIni.
PC : Program counter at 0x801B3BC, which points to a location inside getUartData (see the disassembly screenshot).
Disassembly Observations
Key instructions observed in the disassembly window: MOV r1,r4 – copies the local variable debug_rcv_len=0x8E from r4 to r1. LDR r0,[PC,#116] – loads a value from the address PC+116 into r0. The resulting address is 0x801B434, which is two bytes ahead of the current PC because of a three‑stage pipeline.
The map file reveals that address 0x801B343 stores the global variable debugUartRcvData in the read‑only data segment, whose runtime value is 0x20017EE0 (checked via Memory1).
Step‑by‑Step Execution of shell_cmd_parse
When stepping into shell_cmd_parse (F11), four registers change:
R0 : Receives the first argument puc_buf (pointer 0x20017EE0).
R1 : Receives the second argument us_len ( 0x8E).
LR : Holds the return address ( 0x801B3BC + 8 = 0x801B3C5) to continue after shell_cmd_parse finishes.
PC : Points to the start of shell_cmd_parse ( 0x08029A18).
Register Preservation and Stack Layout
The function preserves LR and registers R4‑R11 because the caller ( getUartData) needs their values after shell_cmd_parse returns. For example, R4 holds the local variable debug_rcv_len.
The stack grows downward from 0x20008948 by 4 * 9 = 0x2008924 bytes to store LR and R4‑R11. Memory inspection shows the saved values:
LR = 0x0801B3C5
R11 = 0xA5A5A5A5
R10 = 0xA5A5A5A5
R9 = 0xA5A5A5A5
R8 = 0xA5A5A5A5
R7 = 0xA5A5A5A5
R6 = 0xA5A5A5A5
R5 = 0x00000000
R4 = 0x0000008EParameter Passing and Stack Allocation
The two parameters puc_buf and us_len are saved into registers r7 and r8 respectively. The function then allocates stack space for a local array of 40 pointers ( char*[]) plus an address slot for end / start. The total allocation is 0xA4 = 164 = 40*4 + 4 bytes, stored partly in r4 and the remainder on the stack.
Visualization of local variables and stack usage is provided in the accompanying screenshots.
Stack Overflow Mechanism
If a command output exceeds the allocated buffer (e.g., pac_argv overrun), the stack inspection reveals that protected data such as LR gets corrupted, leading to a hard fault and program crash.
Overall, the article demonstrates how to trace a function call at the assembly level, interpret register and stack contents, and diagnose potential overflow issues in embedded firmware.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Liangxu Linux
Liangxu, a self‑taught IT professional now working as a Linux development engineer at a Fortune 500 multinational, shares extensive Linux knowledge—fundamentals, applications, tools, plus Git, databases, Raspberry Pi, etc. (Reply “Linux” to receive essential resources.)
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
