ARM64汇编程序读取argc值异常的问题排查
AArch64汇编中argc/x0寄存器值不符合预期的问题解决
问题原因分析
两种编译方式出现异常的核心原因都是程序入口点的内核参数传递未被正确处理:
as+ld直接编译链接
这种方式生成纯手工链接的ELF可执行文件,内核确实会在跳转到_start前将argc存入x0、argv存入x1。你看到寄存器全为0的情况,大概率是调试或运行时未传递任何命令行参数(此时argc=1,仅包含程序名),或是GDB默认启动时未传入参数。部分环境下纯静态链接的ELF可能因缺少栈初始化提示出现异常,但内核本身会为进程分配栈空间。gcc -nostdlib -nostartfiles编译
即便指定了-nostartfiles跳过标准启动代码,GCC默认链接逻辑可能未将_start识别为真正的程序入口,或是插入了隐含的初始化代码,导致内核传递的argc/argv被覆盖,最终x0/x1显示为无关内存地址。
解决办法
针对as+ld编译链
- 运行或调试时务必传入参数,验证代码逻辑可执行:
GDB调试时用以下命令启动,确保参数传入:./code.elf test_arg(gdb) run test_arg - 动态链接环境下,链接时明确指定动态链接器(避免缺失链接器导致的异常):
ld -dynamic-linker /lib/ld-linux-aarch64.so.1 code.o -o code.elf
针对GCC编译链
- 强制链接器将
_start作为程序入口,修改编译命令为:gcc code.s -o code.elf -nostdlib -g -nostartfiles -Wl,-e,_start-Wl,-e,_start参数会让链接器直接将_start作为起始执行点,确保内核传递的argc/argv直接进入x0/x1寄存器。 - 若仍有异常,添加
-static参数强制静态链接,避免动态链接的隐含初始化干扰:gcc code.s -o code.elf -nostdlib -g -nostartfiles -Wl,-e,_start -static
代码逻辑验证
你的汇编代码本身符合AArch64系统调用规范:
x8存储系统调用号,0x5d对应exit系统调用(数值93),x0存储退出码,调用逻辑正确。- 通过
cmp x0, #0x2判断argc是否为2(程序名+1个参数),逻辑符合预期。
内容的提问来源于stack exchange,提问作者pl_Olov3
相关产品推荐
相关产品推荐

