这是来自64位Linux共享对象:
mov rax, [rbp+var_1C+4]
mov rax, [rax]
add rax, 8
mov rax, [rax]
mov rdx, [rbp+var_1C+4]
mov rdi, rdx
call rax
答案 0 :(得分:3)
看起来像是一个虚拟函数调用。
看起来是未优化的编译器输出,假设使用rbp
作为帧指针,并使用add rax,8
而不是像mov rax, [rax+8]
这样的寻址模式。并且无需任何理由重新加载本地,因为它可以在早先加载它之后将指针保存在寄存器中。
看起来它正在准备一个this
指针作为虚函数的arg,以及通过vtable调用虚函数。 How do objects work in x86 at the assembly level?
无论如何这段代码只是一种低效的写作方式
mov rdi, [rbp+var_1C+4] # load a pointer to a local from the stack
mov rax, [rdi] # load the vtable pointer from the start of the object
call [rax+8] # index into the vtable
或者可能设置rdx
,而不仅仅是低效的未优化代码。在x86-64 System V ABI中,rdx
保存函数调用的第3个整数/指针arg。 rdi
拥有第一个(包括this
作为隐藏的第一个arg)。如果先前设置了rsi
,那么可能会有意rdx
传递foo->virtual_function(something, foo)
,因此它就像class something *foo
一样调用,其中foo->virtual_function()
是局部变量或函数arg。
否则它只是Circle c = new Circle();
Cube s = new Cube();
Piramid p = new Piramid();
ArrayList<?> list = new ArrayList<?>();
。
或者它完全不同,恰好看起来就像编译器为虚拟函数调用发出的内容。没有更多的背景,你无法知道。