函数模板机制探究(反汇编)

.cpp文件是一个高级语言,这种形式容易被读懂。为了在系统上运行.cpp程序,每条c++语句都必须转化为低级的机器指令。然后将这些指令打包成可执行目标文件格式,并以二进制形式存储在磁盘中

gcc常用编译选项

选项

作用

-o

产生目标(.i、.s、.o、可执行文件等)

-c

通知gcc取消链接步骤,即编译源码并在最后生成目标文件

-E

只运行C预编译器

-S

告诉编译器产生汇编语言文件后停止编译,产生的汇编语言文件扩展名为.s

-Wall

使gcc对源文件的代码有问题的地方发出警告

-Idir

将dir目录加入搜索头文件的目录路径

-Ldir

将dir目录加入搜索库的目录路径

-llib

链接lib库

-g

在目标文件中嵌入调试信息,以便gdb之类的调试程序调试

 

以下代码示例是对函数模板(泛型编程)的反编译探究

结论:

1.编译器并不是把函数模板处理成能够处理任何任意类的函数

2.编译器从函数模板通过具体类型产生不同的函数

3.编译器会对函数模板进行两次编译

(在声明的地方对模板代码本身进行编译;在调用的地方再对参数替换后的代码进行编译。)

4.编译器在对函数模板编译时与调用的次数无关与调用时参数类型有关

示例代码

#pragma warning(disable : 4996)
#include <iostream>
using namespace std;

template <typename T>
void MySwap(T &a, T &b)
{
	T c = NULL;
	c = a;
	a = b;
	b = c;
}


int main()
{

	int a = 10;
	int b = 20;

	MySwap<int>(a, b);
	MySwap(a, b);
	printf("a:%d,b:%d \n", a, b);

	char c = 'c';
	char d = 'd';

	MySwap<char>(c, d);
	MySwap(c, d);
	printf("c:%c,d:%c \n", c, d);


	system("pause");
	return 0;
}

通过命令行进行编译:g++ -S main.cpp -o main.s

    .file    "main.cpp"
    .text
    .section .rdata,"dr"
__ZStL19piecewise_construct:
    .space 1
.lcomm __ZStL8__ioinit,1,1
    .def    ___main;    .scl    2;    .type    32;    .endef
LC0:
    .ascii "a:%d,b:%d \12\0"
LC1:
    .ascii "c:%c,d:%c \12\0"
LC2:
    .ascii "pause\0"
    .text
    .globl    _main
    .def    _main;    .scl    2;    .type    32;    .endef
_main: 
LFB1503:
    .cfi_startproc
    pushl    %ebp
    .cfi_def_cfa_offset 8
    .cfi_offset 5, -8
    movl    %esp, %ebp
    .cfi_def_cfa_register 5
    andl    $-16, %esp
    subl    $32, %esp
    call    ___main
    movl    $10, 28(%esp)
    movl    $20, 24(%esp)
    leal    24(%esp), %eax
    movl    %eax, 4(%esp)
    leal    28(%esp), %eax
    movl    %eax, (%esp)
    call    __Z6MySwapIiEvRT_S1_    //34 <==> 79
    leal    24(%esp), %eax
    movl    %eax, 4(%esp)
    leal    28(%esp), %eax
    movl    %eax, (%esp)
    call    __Z6MySwapIiEvRT_S1_    //39 <==> 79
    movl    24(%esp), %edx
    movl    28(%esp), %eax
    movl    %edx, 8(%esp)
    movl    %eax, 4(%esp)
    movl    $LC0, (%esp)
    call    _printf
    movb    $99, 23(%esp)
    movb    $100, 22(%esp)
    leal    22(%esp), %eax
    movl    %eax, 4(%esp)
    leal    23(%esp), %eax
    movl    %eax, (%esp)
    call    __Z6MySwapIcEvRT_S1_    //52 <==> 110
    leal    22(%esp), %eax
    movl    %eax, 4(%esp)
    leal    23(%esp), %eax
    movl    %eax, (%esp)
    call    __Z6MySwapIcEvRT_S1_    //57 <==> 110
    movzbl    22(%esp), %eax
    movsbl    %al, %edx
    movzbl    23(%esp), %eax
    movsbl    %al, %eax
    movl    %edx, 8(%esp)
    movl    %eax, 4(%esp)
    movl    $LC1, (%esp)
    call    _printf
    movl    $LC2, (%esp)
    call    _system
    movl    $0, %eax
    leave
    .cfi_restore 5
    .cfi_def_cfa 4, 4
    ret
    .cfi_endproc
LFE1503:
    .section    .text$_Z6MySwapIiEvRT_S1_,"x"
    .linkonce discard
    .globl    __Z6MySwapIiEvRT_S1_
    .def    __Z6MySwapIiEvRT_S1_;    .scl    2;    .type    32;    .endef
__Z6MySwapIiEvRT_S1_:    
LFB1739:
    .cfi_startproc
    pushl    %ebp
    .cfi_def_cfa_offset 8
    .cfi_offset 5, -8
    movl    %esp, %ebp
    .cfi_def_cfa_register 5
    subl    $16, %esp
    movl    $0, -4(%ebp)
    movl    8(%ebp), %eax
    movl    (%eax), %eax
    movl    %eax, -4(%ebp)
    movl    12(%ebp), %eax
    movl    (%eax), %edx
    movl    8(%ebp), %eax
    movl    %edx, (%eax)
    movl    12(%ebp), %eax
    movl    -4(%ebp), %edx
    movl    %edx, (%eax)
    nop
    leave
    .cfi_restore 5
    .cfi_def_cfa 4, 4
    ret
    .cfi_endproc
LFE1739:
    .section    .text$_Z6MySwapIcEvRT_S1_,"x"
    .linkonce discard
    .globl    __Z6MySwapIcEvRT_S1_
    .def    __Z6MySwapIcEvRT_S1_;    .scl    2;    .type    32;    .endef
__Z6MySwapIcEvRT_S1_:
LFB1740:
    .cfi_startproc
    pushl    %ebp
    .cfi_def_cfa_offset 8
    .cfi_offset 5, -8
    movl    %esp, %ebp
    .cfi_def_cfa_register 5
    subl    $16, %esp
    movb    $0, -1(%ebp)
    movl    8(%ebp), %eax
    movzbl    (%eax), %eax
    movb    %al, -1(%ebp)
    movl    12(%ebp), %eax
    movzbl    (%eax), %edx
    movl    8(%ebp), %eax
    movb    %dl, (%eax)
    movl    12(%ebp), %eax
    movzbl    -1(%ebp), %edx
    movb    %dl, (%eax)
    nop
    leave
    .cfi_restore 5
    .cfi_def_cfa 4, 4
    ret
    .cfi_endproc
LFE1740:
    .text
    .def    ___tcf_0;    .scl    3;    .type    32;    .endef
___tcf_0:
LFB1975:
    .cfi_startproc
    pushl    %ebp
    .cfi_def_cfa_offset 8
    .cfi_offset 5, -8
    movl    %esp, %ebp
    .cfi_def_cfa_register 5
    subl    $8, %esp
    movl    $__ZStL8__ioinit, %ecx
    call    __ZNSt8ios_base4InitD1Ev
    leave
    .cfi_restore 5
    .cfi_def_cfa 4, 4
    ret
    .cfi_endproc
LFE1975:
    .def    __Z41__static_initialization_and_destruction_0ii;    .scl    3;    .type    32;    .endef
__Z41__static_initialization_and_destruction_0ii:
LFB1974:
    .cfi_startproc
    pushl    %ebp
    .cfi_def_cfa_offset 8
    .cfi_offset 5, -8
    movl    %esp, %ebp
    .cfi_def_cfa_register 5
    subl    $24, %esp
    cmpl    $1, 8(%ebp)
    jne    L8
    cmpl    $65535, 12(%ebp)
    jne    L8
    movl    $__ZStL8__ioinit, %ecx
    call    __ZNSt8ios_base4InitC1Ev
    movl    $___tcf_0, (%esp)
    call    _atexit
L8:
    nop
    leave
    .cfi_restore 5
    .cfi_def_cfa 4, 4
    ret
    .cfi_endproc
LFE1974:
    .def    __GLOBAL__sub_I_main;    .scl    3;    .type    32;    .endef
__GLOBAL__sub_I_main:
LFB1976:
    .cfi_startproc
    pushl    %ebp
    .cfi_def_cfa_offset 8
    .cfi_offset 5, -8
    movl    %esp, %ebp
    .cfi_def_cfa_register 5
    subl    $24, %esp
    movl    $65535, 4(%esp)
    movl    $1, (%esp)
    call    __Z41__static_initialization_and_destruction_0ii
    leave
    .cfi_restore 5
    .cfi_def_cfa 4, 4
    ret
    .cfi_endproc
LFE1976:
    .section    .ctors,"w"
    .align 4
    .long    __GLOBAL__sub_I_main
    .ident    "GCC: (MinGW.org GCC-8.2.0-3) 8.2.0"
    .def    _printf;    .scl    2;    .type    32;    .endef
    .def    _system;    .scl    2;    .type    32;    .endef
    .def    __ZNSt8ios_base4InitD1Ev;    .scl    2;    .type    32;    .endef
    .def    __ZNSt8ios_base4InitC1Ev;    .scl    2;    .type    32;    .endef
    .def    _atexit;    .scl    2;    .type    32;    .endef
 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值