Ano*_*non 1 assembly stack command-line x86-64
我正在尝试打印 x86-64 中的汇编程序中存在的命令行参数的数量。
据我了解,参数信息存储在堆栈中。
我觉得我缺少一些关于如何检索堆栈中存储的项目的基本知识,但我不知道到底是什么。
.file "args.s"
.globl main
.type main, @function
.section .data
format_string:
.string "Argument: %s\n"
.section .text
main:
pushq %rbp
movq %rsp, %rbp
popq %rsp ; get argc
movq %rsp, %rdi ; move argc to rdi, first parameter register
movq $format_string, %rdi ; pass in the string to be used and give the parameter
call printf
leave
ret
.size main, .-main
Run Code Online (Sandbox Code Playgroud)
你有以下问题(至少):
main.rbp刚刚推送的内容,而不是堆栈上已有的任何内容。rsp(堆栈指针),稍后它会咬您:push / pop 和 call / ret 指令用作rsp指针。main获取,但 64 位调用约定不会将其传递到堆栈上。argcargc传递,因为它是 的第二个参数。由于是 32 位,您可以使用.rdirsiprintfintesiprintf尝试解释argc为字符串,因为您使用的%s是而不是%d格式字符串。%alforprintf归零(这在实践中并不致命,因为它只需要是一个上限,因此其中的任何值都应该在 libc 的非古代版本中工作。较旧的 GCC 计算了间接跳转,因此AL 值高于 8 可能会崩溃.)可选:您的代码不是位置独立的,这是现代系统中推荐的(有时是必需的)。您可以将格式字符串放入其中,.rodata因为它是只读的。
固定版本可能如下所示:
.globl main
main:
push %rbp # rbp not used, for alignment only
mov %edi, %esi # move argc to second parameter register
lea format_string(%rip), %rdi # the format string is the first parameter
xor %eax, %eax # 0 xmm registers used
call printf@plt
xor %eax, %eax # return 0 to behave nicely
pop %rbp
ret
.section .rodata
format_string: .string "Arguments: %d\n"
Run Code Online (Sandbox Code Playgroud)