Files
Embedded-Hacking/WEEK04/WEEK04-01-S.md
2026-03-19 15:01:07 -04:00

3.8 KiB
Raw Permalink Blame History

Embedded Systems Reverse Engineering

Repository

Week 4

Variables in Embedded Systems: Debugging and Hacking Variables w/ GPIO Output Basics

Non-Credit Practice Exercise 1 Solution: Analyze Variable Storage in Ghidra

Answers

Main Function Analysis
Item Value/Location Notes
Main function address 0x10000234 Entry point of program
Age value (hex) 0x2b Optimized constant
Age value (decimal) 43 Original variable value
Variable in memory? No Compiler optimized it away
printf address 0x10003100 Standard library function
stdio_init_all addr 0x100030cc I/O initialization
Format string "age: %d\r\n" Located in .rodata section
Decompiled main() After Renaming
int main(void)
{
    stdio_init_all();
    do {
        printf("age: %d\r\n", 0x2b);
    } while (true);
}
Hex-to-Decimal Conversion
0x2b = (2 × 16) + 11 = 32 + 11 = 43

The compiler replaced both age = 42 and age = 43 with the final constant value 0x2b (43) as an immediate operand in movs r1, #0x2b.

Assembly Listing
movs    r1, #0x2b       ; Load 43 directly into r1 (printf argument)
ldr     r0, [pc, #...]  ; Load format string address
bl      printf           ; Call printf

Reflection Answers

  1. Why did the compiler optimize away the age variable? The compiler performs dead store elimination and constant propagation. The initial assignment age = 42 is immediately overwritten by age = 43 with no intervening reads of the value 42. Since the only value ever observed is 43, the compiler replaces all references to age with the constant 0x2b (43) as an immediate operand. No memory allocation is needed—the value lives entirely in the instruction encoding (movs r1, #0x2b).

  2. In what memory section would age have been stored if it wasn't optimized away? As a local variable declared inside main(), age would have been stored on the stack (in RAM at 0x2000xxxx). The compiler would allocate space by subtracting from SP, store the value with a str instruction, and load it back with ldr before passing it to printf. If age were declared as a global initialized variable, it would be placed in the .data section (RAM, initialized from flash at boot). If declared as static or global but uninitialized, it would go in the .bss section (RAM, zeroed at boot).

  3. Where is the string "age: %d\r\n" stored, and why can't it be in RAM? The format string is stored in the .rodata (read-only data) section in flash memory at 0x1000xxxx. It cannot be in RAM because: (a) string literals are constants that never change, so storing them in limited RAM would waste space; (b) flash is non-volatile—the string persists across power cycles without needing to be copied from anywhere; (c) the XIP (Execute In Place) mechanism allows the CPU to read directly from flash, so .rodata access is efficient.

  4. What would happen if we had used age in a calculation before reassigning it to 43? The compiler would be forced to preserve the value 42 because it's actually read before being overwritten. For example, printf("before: %d\n", age); age = 43; would require the compiler to generate both movs r1, #0x2a (42) for the first print and movs r1, #0x2b (43) for subsequent uses. Alternatively, a calculation like age = age + 1 would allow the compiler to constant-fold 42 + 1 = 43 at compile time and still emit just #0x2b. Only if the value depends on runtime input would the variable require actual memory allocation.