AMD has an ABI specification that describes the calling convention to use on x86-64. All OSes follow it, except for Windows which has it's own x86-64 calling convention. Why?
Does anyone know the technical, historical, or political reasons for this difference, or is it purely a matter of NIHsyndrome?
I understand that different OSes may have different needs for higher level things, but that doesn't explain why for example the register parameter passing order on Windows is rcx - rdx …
x86-64 System V ABI(用于除Windows之外的所有内容)过去常常访问http://x86-64.org/documentation/abi.pdf,但该网站现已脱离互联网.
该文件是否有新的权威主页?
我正在阅读这本书:"计算机系统 - 程序员视角".我发现,在x86-64架构中,我们仅限于6个积分参数,这些参数将被传递给寄存器中的函数.下一个参数将在堆栈上传递.
而且,第一个最多8个FP或矢量args以xmm0..7传递.
为什么不使用浮点寄存器来存储下一个参数,即使参数不是单/双精度变量?
将数据存储在寄存器中比将其存储到存储器然后从存储器中读取它会更有效(据我所知).
所以我有这个C程序示例.
int worship(long john)
{
return 0 * john;
}
int main()
{
return worship(666);
}
Run Code Online (Sandbox Code Playgroud)
该程序集(基本上)看起来像这样:
worship(long):
pushq %rbp
movq %rsp, %rbp
movq %rdi, -8(%rbp)
movl $0, %eax
popq %rbp
ret
main:
pushq %rbp
movq %rsp, %rbp
movl $666, %edi
call worship(long)
popq %rbp
ret
Run Code Online (Sandbox Code Playgroud)
我在阅读堆栈粉碎时遇到了这个问题.在汇编worship(long):部分,它表示movq %rdi, -8(%rbp)我希望它pushq基于我到目前为止阅读的所有内容.这是GCC将参数推送到堆栈的新方法吗?如果有的话,我可以使用编译器标志来切换它吗?
我在llvm clang Apple LLVM 8.0.0版(clang-800.0.42.1)上反汇编代码:
int main() {
float a=0.151234;
float b=0.2;
float c=a+b;
printf("%f", c);
}
Run Code Online (Sandbox Code Playgroud)
我编译时没有-O规范,但我也试过-O0(给出相同)和-O2(实际上计算值并存储它预先计算)
产生的反汇编如下(我删除了不相关的部分)
-> 0x100000f30 <+0>: pushq %rbp
0x100000f31 <+1>: movq %rsp, %rbp
0x100000f34 <+4>: subq $0x10, %rsp
0x100000f38 <+8>: leaq 0x6d(%rip), %rdi
0x100000f3f <+15>: movss 0x5d(%rip), %xmm0
0x100000f47 <+23>: movss 0x59(%rip), %xmm1
0x100000f4f <+31>: movss %xmm1, -0x4(%rbp)
0x100000f54 <+36>: movss %xmm0, -0x8(%rbp)
0x100000f59 <+41>: movss -0x4(%rbp), %xmm0
0x100000f5e <+46>: addss -0x8(%rbp), %xmm0
0x100000f63 <+51>: movss %xmm0, -0xc(%rbp)
...
Run Code Online (Sandbox Code Playgroud)
显然它正在做以下事情:
我试图根据 godbolt.org 上 c++ 中的平方函数来理解这一点。显然,返回、参数和局部变量使用 \xe2\x80\x9crbp -alignment\xe2\x80\x9d 来实现此函数。\n有人可以解释一下这是如何实现的吗?\n在这种情况下 rbp +alignment 会做什么?
\nint square(int num){\n int n = 5;// just to test how locals are treated with frame pointer\n return num * num;\n}\nRun Code Online (Sandbox Code Playgroud)\n编译器(x86-64 gcc 11.1)
\n生成的程序集:
\nsquare(int):\n push rbp\n mov rbp, rsp \n mov DWORD PTR [rbp-20], edi. ;\\\\Both param and local var use rbp-*\n mov DWORD PTR[rbp-4], 5. ;//\n mov eax, DWORD PTR [rbp-20]\n imul eax, eax\n pop rbp\n ret\n\nRun Code Online (Sandbox Code Playgroud)\n assembly ×5
x86-64 ×5
c ×2
abi ×1
c++ ×1
compilation ×1
gcc ×1
linux ×1
llvm-codegen ×1
stack ×1
stack-frame ×1
windows ×1
x86 ×1