2009-11-24 63 views
0

是否有任何教程或解释任何地方的C++对象如何翻译成汇编指令移动寄存器之间的数据...汇编和C++关系

我真的不明白我们是如何在更高层次的语言操纵物体在哪里汇编程序你本质上是在寄存器之间移动数据?加上对他们做一些基本的操作。

回答

3

声明:我将使用IA-32装配样品。

通常,每个对象都是分配在堆上(通过new调用)或stacK(基本上,通过移动esp为其预留内存)分配的内存结构驻留块。内存分配后,指针传递给对象构造函数进行初始化(注意ctor可以内联,这样就不会产生call)。

通常,每个具有虚拟方法的对象都有一个指向虚拟方法的表(通常称为VMT或vtable,它存储指向函数的指针,当您调用虚拟方法时,获取此方法的地址并调用它。看起来是这样的

mov ecx, [this] 
mov ebx, vtable 
push [arg2] 
push [arg1] 
call [ebx + OFFSET_foo] ; this->foo(arg1, arg2); 

注意,在此示例中我已经证明this通过ECX传递和args是从右到左的顺序,这是thiscall convention,在VC++使用默认情况下,例如,通过堆栈传递其他编译器可能会采用其他惯例,如链接文章所示。

对于非虚拟调用,不需要查找表。所以,代码看起来像

mov ecx, [this] 
push [args] 
push [arg1] 
call bar ; this->bar(arg1, arg2) 

这就是为什么非虚方法可以更快一点被执行 - 它的地址是众所周知的,所以编译器就可以开始遇到call码解码之前他们的代码。

在某些调用约定(例如fastcall)中,参数通过寄存器传递,在某些情况下可以更快。

在大多数调用约定中,如果通过寄存器,通过FPU堆栈(如果这是浮点或通过堆栈)适合该寄存器,则返回结果iss。

如果您想了解更多关于翻译的C++代码组件,我建议你到

  • 尽量让你的编译器生成汇编(通常-S键在装配过程中上市;它可以设定VC++项目设置也是如此);

  • 尝试反汇编代码例如使用优秀的IDA反汇编程序。它有free version它。它通过为局部变量提供符号名称,识别库函数等方面帮助很大。

祝你好运!

+0

谢谢!这就说得通了!! :) – 2009-11-25 23:13:28