相关疑难解决方法(0)

Why does Windows64 use a different calling convention from all other OSes on x86-64?

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 …

windows x86-64 calling-convention

97
推荐指数
4
解决办法
2万
查看次数

x86-64 System V ABI在哪里记录?

x86-64 System V ABI(用于除Windows之外的所有内容)过去常常访问http://x86-64.org/documentation/abi.pdf,但该网站现已脱离互联网.

该文件是否有新的权威主页?

linux assembly x86-64 abi calling-convention

43
推荐指数
2
解决办法
2万
查看次数

为什么不在XMM向量寄存器中存储函数参数?

我正在阅读这本书:"计算机系统 - 程序员视角".我发现,在x86-64架构中,我们仅限于6个积分参数,这些参数将被传递给寄存器中的函数.下一个参数将在堆栈上传递.

而且,第一个最多8个FP或矢量args以xmm0..7传递.

为什么不使用浮点寄存器来存储下一个参数,即使参数不是单/双精度变量?

将数据存储在寄存器中比将其存储到存储器然后从存储器中读取它会更有效(据我所知).

x86 assembly x86-64 parameter-passing calling-convention

15
推荐指数
1
解决办法
1200
查看次数

为什么GCC使用Mov而不是推入函数调用?

所以我有这个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将参数推送到堆栈的新方法吗?如果有的话,我可以使用编译器标志来切换它吗?

c assembly stack gcc compilation

6
推荐指数
1
解决办法
1143
查看次数

为什么clang用-O0生成效率低的asm(对于这个简单的浮点和)?

我在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)

显然它正在做以下事情:

  1. 将两个浮点数加载到寄存器xmm0和xmm1上
  2. 把它们放在堆栈中
  3. 从堆栈加载一个值(不是之前的xmm0)到xmm0
  4. 执行添加. …

c assembly x86-64 compiler-optimization llvm-codegen

4
推荐指数
1
解决办法
333
查看次数

为什么参数分配在帧指针下方而不是上方?

我试图根据 godbolt.org 上 c++ 中的平方函数来理解这一点。显然,返回、参数和局部变量使用 \xe2\x80\x9crbp -alignment\xe2\x80\x9d 来实现此函数。\n有人可以解释一下这是如何实现的吗?\n在这种情况下 rbp +alignment 会做什么?

\n
int square(int num){\n    int n = 5;// just to test how locals are treated with frame pointer\n    return num * num;\n}\n
Run Code Online (Sandbox Code Playgroud)\n

编译器(x86-64 gcc 11.1)

\n

生成的程序集:

\n
square(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\n
Run Code Online (Sandbox Code Playgroud)\n

c++ assembly x86-64 calling-convention stack-frame

2
推荐指数
1
解决办法
525
查看次数