为什么在英特尔movl和popl之间需要NOP?

时间:2016-08-28 15:22:47

标签: c++ oop compilation

我正在尝试使用Ubuntu在C ++中找出更好的简单访问函数编码。构造函数和Set访问器都包含一个NOP,我找不到原因。

我的MWE:

class A
{
public:
  A(void){Aa = 13;};
  int GetA(void){ return Aa;}
  void SetA(int a){ Aa = a;}
private:
  int Aa;
};

int main()
{
    A MyA;
    MyA.SetA(11);
    return MyA.GetA();
}

构造函数的代码,由...编译 gcc版本5.4.0 20160609(Ubuntu 5.4.0-6ubuntu1~16.04.2) 是

_ZN1AC2Ev:
.LFB1:
    .cfi_startproc
    pushl   %ebp
    .cfi_def_cfa_offset 8
    .cfi_offset 5, -8
    movl    %esp, %ebp
    .cfi_def_cfa_register 5
    movl    8(%ebp), %eax
    movl    $13, (%eax)
    nop
    popl    %ebp
    .cfi_restore 5
    .cfi_def_cfa 4, 4
    ret
    .cfi_endproc

我无法弄清楚的是,movl $13, (%eax)是注册间接内存的直接内存,而popl %ebp是堆栈读取(即读取内存),NOP的功能可能是什么?我想这可能是一些内存时序技巧,但我没有看到任何理由为什么内存写入和堆栈读取(即读取内存)可能会干扰(我的意思是:在编程级别)并需要一些延迟。而且,如果确实如此,为什么在编程层面?

Set访问者也在使用NOP:

_ZN1A4SetAEi:
.LFB4:
    .cfi_startproc
    pushl   %ebp
    .cfi_def_cfa_offset 8
    .cfi_offset 5, -8
    movl    %esp, %ebp
    .cfi_def_cfa_register 5
    movl    8(%ebp), %eax
    movl    12(%ebp), %edx
    movl    %edx, (%eax)
    nop
    popl    %ebp
    .cfi_restore 5
    .cfi_def_cfa 4, 4
    ret
    .cfi_endproc
.LFE4:

而get访问器函数本身不使用它:

    _ZN1A4GetAEv:
    .LFB3:
        .cfi_startproc
        pushl   %ebp
        .cfi_def_cfa_offset 8
        .cfi_offset 5, -8
        movl    %esp, %ebp
        .cfi_def_cfa_register 5
        movl    8(%ebp), %eax
        movl    (%eax), %eax
        popl    %ebp
        .cfi_restore 5
        .cfi_def_cfa 4, 4
        ret
        .cfi_endproc
.LFE3:

0 个答案:

没有答案