如何在X86-64 AT&T语法汇编中打印命令行参数?
X86-64 AT&T语法汇编实现打印所有命令行参数
要实现打印所有命令行参数,核心是通过循环遍历argv指针数组,结合argc控制循环次数。你提供的原代码仅打印了参数总数和第一个参数,以下是修改后的完整实现:
.globl main main: push %rbp # 栈对齐,用rbp维护栈帧基址 mov %rsp, %rbp # 打印参数总数 mov %edi, %esi # 将argc传入printf的第二个参数位置 lea format_argc(%rip), %rdi # 加载参数总数的格式化字符串 xor %eax, %eax # 未使用XMM寄存器,需置0符合调用规范 call printf@plt # 初始化循环:遍历所有argv元素 xor %ecx, %ecx # ecx作为循环计数器,初始为0 loop_start: cmp %ecx, %edi # 比较计数器与argc,ecx >= argc时退出循环 jle loop_end # 获取当前argv[ecx]的指针并打印 lea format_arg(%rip), %rdi # 加载参数打印的格式化字符串 mov %ecx, %edx # 将计数器传入格式化字符串的%d位置 mov 16(%rbp), %rsi # 取argv数组起始地址 mov (%rsi, %rcx, 8), %rsi # 当前参数的字符串指针传入%s位置 xor %eax, %eax call printf@plt inc %ecx # 计数器自增 jmp loop_start loop_end: xor %eax, %eax # 返回0,程序正常退出 pop %rbp ret .section .rodata format_argc: .string "总参数数量: %d\n" format_arg: .string "参数%d: %s\n"
关键逻辑说明
- 参数访问规则:X86-64 System V调用约定中,
main的argc存在%edi寄存器,argv是指针数组,其起始地址位于栈上%rbp+16处(栈帧布局:%rbp占8字节 + 返回地址占8字节 +argv)。 - 循环控制:用
%ecx作为循环计数器,从0开始递增,每次与%edi(argc)比较,当计数器达到argc时跳出循环。 - 数组寻址:
argv的每个元素是8字节的字符串指针,通过(%rsi, %rcx, 8)的寻址方式计算argv[ecx]的地址(基址+索引×步长)。 - printf调用规范:每次调用
printf前必须将%eax置0,告诉函数没有使用浮点参数(XMM寄存器),符合System V调用约定要求。
内容的提问来源于stack exchange,提问作者Anon
相关产品推荐
相关产品推荐

