You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ARM架构GNU/Linux下汇编程序执行流程及最小实现问询

Understanding ARM Assembly Execution on GNU/Linux, C Runtime Role, and Minimal Exit Code Implementation

Great question—let’s break this down step by step to demystify how your assembly program runs, what the C standard library (and those crt*.o files) actually do, and how to build the smallest possible program that returns exit code 5.

First: What’s the C Standard Library & crt*.o Files Doing Here?

When you linked with crt1.o, crti.o, crtn.o, and libc.so, you’re pulling in the C runtime (CRT) infrastructure—here’s the breakdown of each component:

  • crt1.o: This is the real entry point for your program (not main!). The Linux kernel doesn’t know or care about main; it jumps to the _start symbol defined in crt1.o. This file sets up the initial stack, initializes global variables (like .data and .bss segments), and calls __libc_start_main from libc.so.
  • __libc_start_main (from libc.so): This function handles the heavy lifting: it runs any pre-main initialization (like global constructors), calls your main function, captures its return value (stored in w0), and then calls exit() to pass that return code to the kernel.
  • crti.o & crtn.o: These files wrap the .init and .fini sections of your program. Code in .init runs before main (e.g., setting up library state), and .fini runs after main exits (e.g., cleaning up resources). They’re mostly for supporting C++ style constructors/destructors or library initialization.
  • libc.so: Beyond __libc_start_main and exit, it provides all the standard C functions, but in your simple program, you’re only using it to bridge your main function to the kernel’s exit system call.

Minimal Assembly Program to Return Exit Code 5 (No C Library Needed)

You don’t actually need the C runtime to return an exit code—you can directly invoke the Linux system call yourself. Here’s the minimal AArch64 assembly code:

.text
.global _start  // Tell the linker this is the entry point
_start:
    mov     x0, #5          // Store exit code 5 in x0 (first system call argument)
    mov     x8, #93         // Linux exit system call number is 93 for AArch64
    svc     #0              // Trigger the system call to the kernel

To build and run this:

as prog.s -o prog.o
ld prog.o -o prog
./prog; echo $?  // Outputs 5

This skips all the C runtime overhead—your _start is the direct entry point the kernel jumps to, and you’re calling the exit system call directly.

Full Execution Steps When You Run ./prog

Let’s walk through exactly what happens from typing the command to seeing the exit code:

  1. Shell Initiates Execution: Your shell (e.g., bash) parses the ./prog command and calls the execve() system call, passing the path to your program and any arguments.
  2. Kernel Loads the ELF Binary:
    • The kernel reads the ELF header of prog to find the program segments (.text, .data, etc.).
    • It maps these segments into the new process’s virtual address space.
    • It sets up the process’s stack (initializes the stack pointer sp to a valid memory location).
    • It sets the program counter (pc) to the entry point defined in the ELF header (your _start symbol).
  3. Kernel Switches to User Mode: The kernel hands control to the user-space process, and the CPU starts executing code at _start.
    • For your original libc-linked program: _start from crt1.o initializes the runtime, calls __libc_start_main, which runs your main function. When main returns, __libc_start_main calls exit(w0), which eventually triggers the exit system call.
    • For the minimal program: The CPU executes the three instructions immediately, triggering the exit system call.
  4. Kernel Handles Exit: The exit system call tells the kernel to clean up the process: close open file descriptors, free allocated memory, and update the process’s exit status to the value in x0 (5).
  5. Shell Reports Exit Code: The kernel returns the exit status to the shell (the parent process). When you run echo $?, the shell prints the stored exit status of the last executed command—your program’s 5.

内容的提问来源于stack exchange,提问作者jregalad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 08:53:12