【问题标题】:Assembly code: logic behind calculating offset into stack汇编代码:计算堆栈偏移量的逻辑
【发布时间】:2014-06-28 10:52:28
【问题描述】:

我是汇编编程的新手,我正在尝试解码由 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] fun中栈指针减16的逻辑是什么,只涉及一个局部变量。不应该是8吗?

谢谢。

【问题讨论】:

标签: c gcc assembly


【解决方案1】:
  1. 一般来说,您只能猜测编译器为什么会这样做。在这种情况下,显然没有启用优化,因此编译器可能只是分配了一个没有得到优化的最坏情况堆栈帧。您可能想尝试启用优化。
  2. rbp 指向入栈的rbp,rbp+8 是返回地址,rbp+16 是第一个参数,rbp+24 是第二个参数。请注意,在 64 位模式中,堆栈以 8 字节块的形式使用。
  3. 大概调用约定要求 16 字节对齐。

对于点 [2] 和 [3],请参阅相应的 abi 文档。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-11-05
    • 1970-01-01
    • 2017-11-18
    • 2018-09-24
    • 2021-11-18
    • 2013-02-25
    • 2019-10-01
    相关资源
    最近更新 更多