刚刚启动了一个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)
我对上述内容有几点疑问:
dword ptr[x]
实际上意味着什么?指针地址引用x?ecx
?我理解这是因为正在调用resize()
函数,但为什么ecx特别注册?mov dword ptr [x],ecx
部分唯一的装配线?我试图了解指针被取消引用的成本。
答案 0 :(得分:4)
mov ecx, dword ptr [x]
表示:将dword(32位)从内存位置x
移动到ecx
寄存器。它只是汇编语言的一种语法特性,表示存在内存访问,并且它的大小为32位。
在考虑指针时,有必要记住关于底层架构的一些观点:
因此,当您在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
寄存器,因为this
指针位于Microsoft fastcall convention的位置。