我编写了一个非常小的实现并使用g++ --save-temps opt.cpp 编译它们。此标志保留临时预处理文件、程序集文件和目标文件。我用virtual 关键字运行了一次,没有运行一次。这是程序。
class Base
{
public:
virtual int fnc(int nm)
{
int i = 0;
i += 3;
return i;
}
void process()
{
int x = 9;
for(int i = 0; i < 1000; i++)
{
x += i;
}
}
};
int main(int argc, char* argv[]) {
Base b;
return 0;
}
当我使用 virtual 关键字运行时,在 x86_64 Linux 机器上生成的程序集是:
.file "opt.cpp"
.section .text._ZN4Base3fncEi,"axG",@progbits,_ZN4Base3fncEi,comdat
.对齐 2
.weak _ZN4Base3fncEi
.type _ZN4Base3fncEi, @function
_ZN4Base3fncEi:
.LFB0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
movq %rdi, -24(%rbp)
movl %esi, -28(%rbp)
movl $0, -4(%rbp)
添加 $3, -4(%rbp)
movl -4(%rbp), %eax
流行音乐%rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE0:
.size _ZN4Base3fncEi, .-_ZN4Base3fncEi
。文本
.globl 主要
.type 主要,@function
主要的:
.LFB2:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
subq $32, %rsp
movl %edi, -20(%rbp)
movq %rsi, -32(%rbp)
movq %fs:40, %rax
movq %rax, -8(%rbp)
xorl %eax, %eax
leaq 16+_ZTV4Base(%rip), %rax
movq %rax, -16(%rbp)
移动 $0, %eax
movq -8(%rbp), %rdx
xorq %fs:40, %rdx
耶.L5
调用 __stack_chk_fail@PLT
.L5:
离开
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE2:
.size 主要,.-main
.weak _ZTV4Base
.section .data.rel.ro.local._ZTV4Base,"awG",@progbits,_ZTV4Base,comdat
.align 8
.type _ZTV4Base, @object
.size _ZTV4Base, 24
_ZTV4基地:
.quad 0
.quad _ZTI4Base
.quad _ZN4Base3fncEi
.weak _ZTI4Base
.section .data.rel.ro._ZTI4Base,"awG",@progbits,_ZTI4Base,comdat
.align 8
.type _ZTI4Base, @object
.size _ZTI4Base, 16
_ZTI4基地:
.quad _ZTVN10__cxxabiv117__class_type_infoE+16
.quad _ZTS4Base
.weak _ZTS4Base
.section .rodata._ZTS4Base,"aG",@progbits,_ZTS4Base,comdat
.type _ZTS4Base, @object
.size _ZTS4Base, 6
_ZTS4Base:
.string "4Base"
.ident“GCC:(Ubuntu 6.2.0-5ubuntu12)6.2.0 20161005”
.section .note.GNU-stack,"",@progbits
没有virtual 关键字,最终的组装是:
.file “opt.cpp”
。文本
.globl 主要
.type 主要,@function
主要的:
.LFB2:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
movl %edi, -20(%rbp)
movq %rsi, -32(%rbp)
移动 $0, %eax
流行音乐%rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE2:
.size 主要,.-main
.ident“GCC:(Ubuntu 6.2.0-5ubuntu12)6.2.0 20161005”
.section .note.GNU-stack,"",@progbits
现在与已发布的问题不同,此示例甚至没有使用虚拟方法,并且生成的程序集要大得多。我没有尝试使用优化进行编译,但试一试。