汇编程序和C ++关系

时间:2009-11-24 17:53:25

标签: c++ assembly

关于C ++对象如何转换为在寄存器之间移动数据的汇编程序指令,是否有任何教程或解释......

我真的不明白我们是如何在高级语言中操作对象的,在Assembler中你实际上是在寄存器之间移动数据?加上对它们进行一些基本操作。

1 个答案:

答案 0 :(得分: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)中,参数通过寄存器传递,在某些情况下可以更快。

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

如果您想了解有关将C ++代码转换为汇编的更多信息,我建议

  • 尝试让编译器在编译期间生成汇编列表(通常是-S键;它也可以在VC ++项目设置中设置);

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

祝你好运!