为什么Intel movl和popl之间需要NOP? 我试图用C++语言来更好地编码C++中的一个简单的访问函数。构造函数和Set访问器都包含NOP,我找不到原因
我的MWE:为什么Intel movl和popl之间需要NOP? 我试图用C++语言来更好地编码C++中的一个简单的访问函数。构造函数和Set访问器都包含NOP,我找不到原因,c++,oop,compilation,C++,Oop,Compilation,我的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
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)
是
我不明白的是,在movl$13、(%eax)
这是一个用于注册间接内存的立即数和popl%ebp
这是堆栈读取(即读取内存)之间,NOP的功能是什么?我想这可能是一些内存计时技巧,但我不明白为什么内存写入和堆栈读取(即读取内存)会产生干扰(我的意思是:在编程级别)并需要一些延迟。如果是,为什么是在编程级别
集合存取器也使用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 accessor函数本身不使用它时:
_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:
盯着未优化的代码看是没有用的,代码生成器很少尝试生成最佳代码。优化器的工作是使其成为智能代码。许多可能的理论,可能是任何析构函数调用的占位符,但没有。可能有意允许在右大括号上设置断点。不要在上面浪费时间,只看/O2代码。@Hans Passant这只是出于我的好奇心。否则,使用-O1或-O2,主程序将简化为“movl$11,%eax;ret”。这是正确的,但对OOP编码的操作几乎没有深入了解。:)
_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: