汇编代码:计算偏移到堆栈的逻辑

时间:2014-05-10 20:26:35

标签: c gcc assembly

我是汇编编程的新手,我正在尝试解码由64但是GNC编译器(GCC)发出的汇编。

void fun(int a, int b)
    {
    int h=0;
    }

    int main()
    {
    int d = 0;
    fun(d,10);
    }

这个程序集是

.globl fun
    .def    fun;    .scl    2;  .type   32; .endef
fun:
    pushq   %rbp     #
    movq    %rsp, %rbp   #,
    subq    $16, %rsp    #,
    movl    %ecx, 16(%rbp)   # a, a
    movl    %edx, 24(%rbp)   # b, b
    movl    $0, -4(%rbp)     #, h
    leave
    ret
    .def    __main; .scl    2;  .type   32; .endef
.globl main
    .def    main;   .scl    2;  .type   32; .endef
main:
    pushq   %rbp     #
    movq    %rsp, %rbp   #,
    subq    $48, %rsp    #,
    call    __main   #
    movl    $0, -4(%rbp)     #, d
    movl    -4(%rbp), %eax   # d, tmp59
    movl    $10, %edx    #,
    movl    %eax, %ecx   # tmp59,
    call    fun  #
    leave
    ret

我对这次集会有些怀疑。

[1]从main中的堆栈指针中减去48的精确算法是什么。 [2]有趣的是,我相信从基本指针到访问函数参数的偏移量从16开始(返回地址和基本指针是两个内存位置到堆栈中(堆栈帧是8个字节),但为什么下一个偏移量是24而不是16。

    movl    %ecx, 16(%rbp)   # a, a
    movl    %edx, 24(%rbp)   # b, b

为什么不是:         movl%ecx,16(%rbp)#a,a         movl%edx,20(%rbp)#b,b

[3]当只涉及一个局部变量时,有趣的是从堆栈指针中减去16的逻辑是什么。不应该是8?

感谢。

1 个答案:

答案 0 :(得分:0)

  1. 一般来说,你只能猜测编译器为什么会这样做。在这种情况下,显然没有启用优化,因此编译器可能只是分配了一个最坏情况的堆栈帧,它只是没有得到优化。您可能希望尝试启用优化。
  2. rbp指向堆栈上的推送rbprbp+8是返回地址,rbp+16是第一个参数,rbp+24是第二个参数。请注意,在64位模式下,堆栈以8字节块的形式使用。
  3. 大概是调用约定要求16字节对齐。
  4. 对于分数[2][3],请参阅相应的abi文档。