【发布时间】:2016-10-04 18:55:14
【问题描述】:
最近我一直在从书 Programming from the Ground Up 中学习 x86 汇编,但我有一台 x86-64 计算机,所以事情开始出现问题(在本书的早期阶段)。我到了处理函数的部分,特别是 power 示例。在这个例子中,他将参数压入堆栈,然后在函数的后面将它们复制到寄存器中。他的代码如下所示:
pushl $3 # second argument
pushl $2 # first argument
call power # call function
...
power:
pushl %ebp # save old base pointer
movl %esp, %ebp # make stack pointer the base pointer
subl $4, %esp # get room for our local storage
movl 8(%ebp), %ebx # put first argument in %eax
movl 12(%ebp), %ecx # put second argument in %ecx
当然,这是 32 位的,而我正在运行 64 位,所以我尝试更新寄存器和指令后缀以得到类似这样的结果(这次应该不需要 cmets):
pushq $3
pushq $2
call power
...
power:
pushq %rbp
movq %rsp, %rbp
subq $4, %rsp
movq 8(%rbp), %rdi
movq 12(%rbp), %rsi
鉴于,我可能只是混淆了我应该使用的实际寄存器,但我并不完全确定。我所知道的是,当我在命令 movq 8(%rbp), %rdi 之后在 GNU 调试器中打印 %rdi 的值时,考虑到我得到以下信息,在我看来它似乎具有内存地址而不是它的内容:
(gdb) i r rdi
rdi 0x400081 4194433
另外,有没有像组装爱好者论坛这样的东西?我已经进行了一些基本的搜索,但还没有找到(x86 程序集论坛除外,它只有一个帖子,这是一篇欢迎帖子,http://www.x86-assembly.org/)。
谢谢!
【问题讨论】:
-
参数不在 x86-64 ABI 的堆栈中。
-
qwords 是 8 字节而不是 4,因此将
movq 8(%rbp), %rdi更改为movq 16(rbp)(与下一行相同),您可以使用寄存器作为参数,系统调用需要使用x86-64-abi. -
Why first parameter is 16($rbp) and not 8($rbp)? 显示了一个具有 10 个整数参数的示例,因此最后 4 个实际上在堆栈上。 (不像这里你发明了自己的调用约定,即使前 2 个 args 也使用 stack-args)
标签: linux function assembly x86-64 stack-memory