我正在研究c ++如何通过汇编语言调用正确的成员函数。我附带的简单程序如下:
class A
{
public:
virtual void show() {}
};
class B : public A
{
public:
void show() {}
};
int main()
{
A* pA = new B;
pA->show();
return 0;
}
其组装如下:
main:
.LFB2:
.cfi_startproc
.cfi_personality 0x3,__gxx_personality_v0
pushq %rbp
.cfi_def_cfa_offset 16
movq %rsp, %rbp
.cfi_offset 6, -16
.cfi_def_cfa_register 6
pushq %rbx
subq $24, %rsp
movl $8, %edi
.cfi_offset 3, -24
call _Znwm <<<================ 1
movq %rax, %rbx
movq %rbx, %rax
movq %rax, %rdi
call _ZN1BC1Ev
.L11:
movq %rbx, %rax
movq %rax, -24(%rbp)
movq -24(%rbp), %rax
movq (%rax), %rax
movq (%rax), %rdx
movq -24(%rbp), %rax
movq %rax, %rdi
call *%rdx <<<=== 2
movl $0, %eax
addq $24, %rsp
popq %rbx
leave
ret
.cfi_endproc
我的问题是:
在*
之前汇编语法呼叫或跳转指令在AT&T的绝对地址使用。这意味着它将跳转到寄存器中包含的地址。另一种选择是相对跳转,相对于当前指令。
从GNUas
手册:
AT&T绝对(相对于PC相对)跳转/呼叫操作数的前缀为*。它们在Intel语法中是无界的。
在您的代码中,有必要调用寄存器中的地址。调用pA->show()
需要查找以查看正确的函数是什么。这是因为它是类A上的虚函数。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句