用于取消引用指针的程序集

时间:2014-03-23 19:16:10

标签: c++ pointers assembly x86

刚刚启动了一个visual studio项目来查看用于取消引用指针的程序集。我有这个C ++:

int main(){
    std::vector<int>* x = new std::vector<int>();
    x->resize(10);
    return 1;
}

asm(用于取消引用):

mov         dword ptr [x],ecx 
    x->resize(10);
push        0Ah  
mov         ecx,dword ptr [x]  
call        std::vector<int,std::allocator<int> >::resize (0BC124Eh) 

我对上述内容有几点疑问:

  1. dword ptr[x]实际上意味着什么?指针地址引用x?
  2. 为什么将上述值复制到ecx?我理解这是因为正在调用resize()函数,但为什么ecx特别注册?
  3. 解除引用mov dword ptr [x],ecx部分唯一的装配线?
  4. 我试图了解指针被取消引用的成本。

1 个答案:

答案 0 :(得分:4)

C ++指针和底层架构

mov ecx, dword ptr [x]表示:将dword(32位)从内存位置x移动到ecx寄存器。它只是汇编语言的一种语法特性,表示存在内存访问,并且它的大小为32位。

在考虑指针时,有必要记住关于底层架构的一些观点:

  • 处理器有少量寄存器(大约16-32,具体取决于架构),它存储机器大小的整数(x86为32位,x64为64位)。
  • 所有其余数据必须保存在内存中,并且总是通过指针访问(即使您没有在代码中声明显式指针)。

因此,当您在C ++中实际声明指向对象的指针时,大多数情况下它不会影响生成的代码。例如,以下两段代码在使用优化进行编译时将生成相同的汇编代码:

Obj a;
a.function();

Obj a;
Obj *b = &a;
b->function();

与代码的唯一区别在于您在堆上分配内存(通过new)。这是一个额外的函数调用,它还意味着你必须在最后注意delete它(你的演示代码错过了!)。除此之外,优化编译器将为x的所有实际使用生成同等性能的代码。我猜你的代码是在没有优化的情况下编译的,否则内存访问将完全被优化掉。

在指向对象的单个指针是特殊情况的情况下:内存中的所有对象必须通过指针访问,即使它们没有在C ++中明确显示。因此,一旦启用优化,单指针的情况就会与无指针的情况相同。

指针链/链接结构

关于指针链的一个词,那些变慢,需要多次内存访问。这通常发生在链接结构中:

struct C { int value; };
struct B { C* c; };
struct A { B* b; };

A a = initialize_A();
a->b->c->value = 7;

在这种情况下,需要取消引用几个指针才能访问最终的value

为何选择ecx?

向量的地址被复制到ecx寄存器,因为this指针位于Microsoft fastcall convention的位置。