代码之家  ›  专栏  ›  技术社区  ›  PepeHands

gcc是否保留被调用方保存寄存器

  •  0
  • PepeHands  · 技术社区  · 8 年前

    正如你可能已经猜到的,问题是 gcc 自动保存被叫方保存寄存器,还是我自己保存?我以为 全球气候变化委员会 我会这么做,但当我写这段代码时

    void foo(void) {
        __asm__ volatile ("mov $123, %rbx");
    }
    
    void main(void) {
        foo();
    }
    

    之后 gcc a.c && objdump -d a.out 我看到了这个

    00000000004004f6 <foo>:
      4004f6:   55                      push   %rbp
      4004f7:   48 89 e5                mov    %rsp,%rbp
      4004fa:   48 c7 c3 7b 00 00 00    mov    $0x7b,%rbx
      400501:   90                      nop
      400502:   5d                      pop    %rbp
      400503:   c3                      retq   
    
    0000000000400504 <main>:
      400504:   55                      push   %rbp
      400505:   48 89 e5                mov    %rsp,%rbp
      400508:   e8 e9 ff ff ff          callq  4004f6 <foo>
      40050d:   90                      nop
      40050e:   5d                      pop    %rbp
      40050f:   c3                      retq
    

    根据x86-64 ABI %rbx 是被调用方保存寄存器,但在此代码中 全球气候变化委员会 未将其保存在 foo 在修改之前。只是因为我不使用 %红血球 调用后在main函数中 foo() 或者是因为 全球气候变化委员会 没有这样的车库,我不得不自己把它存起来 富奥牌手表 修改之前?

    2 回复  |  直到 8 年前
        1
  •  3
  •   Chris Dodd    8 年前

    Gcc将自动保存和恢复所有被叫方保存寄存器 它知道的 。它知道自己使用的寄存器,但只有当你告诉它时,它才会知道内联程序集中使用的寄存器。这就是“打击者”名单的目的:

    void foo(void) {
        __asm__ volatile ("mov $123, %%rbx" : : : "rbx");
    }
    

    现在编译器知道您正在使用/修改rbx,因此如果需要,它会保存它。

    请注意,您确实想这样做,而不是自己尝试保存它,因为这样,如果gcc还想在这个函数中使用寄存器,它将只保存一次。

        2
  •  1
  •   Weather Vane    8 年前

    用死记硬背的方式保存和恢复每个寄存器,这将是一段相当棘手的代码。编译器将寄存器保存在它编译过的C代码中,但在这里,你是自己的,gcc不知道你的意图是什么。

    装配工可以让你钻到发动机罩下面,但它不会替你更换火花塞。