函數模板機制探究(反彙編)

.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
 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章