引用和宏定義的彙編實現

引用的實現實質上跟指針是一樣的,如下:

//------------------------------------------------

#include <iostream>

using namespace std;

int main()
{
 int a = 3;
 int &ref_a = a;

 ref_a += 2;
 return 0;
}

//-----------------------------------------------

 

1:    #include <iostream>
2:
3:    using namespace std;
4:
5:    int main()
6:    {
00401030 55                   push        ebp
00401031 8B EC                mov         ebp,esp
00401033 83 EC 48             sub         esp,48h
00401036 53                   push        ebx
00401037 56                   push        esi
00401038 57                   push        edi
00401039 8D 7D B8             lea         edi,[ebp-48h]
0040103C B9 12 00 00 00       mov         ecx,12h
00401041 B8 CC CC CC CC       mov         eax,0CCCCCCCCh
00401046 F3 AB                rep stos    dword ptr [edi]
7:        int a = 3;
00401048 C7 45 FC 03 00 00 00 mov         dword ptr [ebp-4],3  ; a存儲在內存中的[ebp-4]處,初值爲3
8:        int &ref_a = a;
0040104F 8D 45 FC             lea         eax,[ebp-4]   ; 取[ebp-4]地址給eax,(ref_a = &a)
00401052 89 45 F8             mov         dword ptr [ebp-8],eax  ; 將此地址值保存在[ebp-8]處,作爲ref_a的內容(也就是其所指向的變量的地址)
9:
10:       ref_a += 2;
00401055 8B 4D F8             mov         ecx,dword ptr [ebp-8]  ; 地址賦給ecx
00401058 8B 11                mov         edx,dword ptr [ecx]  ; 取ecx中保存的地址處的值賦給edx(也就是a的值)
0040105A 83 C2 02             add         edx,2    ; 加2
0040105D 8B 45 F8             mov         eax,dword ptr [ebp-8]  ; 將a的地址賦給eax (eax = &a)
00401060 89 10                mov         dword ptr [eax],edx  ; 把計算結果保存到a的地址空間處,實現了對a的改變
11:       return 0;
00401062 33 C0                xor         eax,eax
12:   }

---------------------------------------------

 

觀察宏的反彙編代碼


//---------------------------------------------

#include <stdio.h>

#define CMP(x,y) ( (x) > (y) ? 1 : -1)

int main()
{
    int r = CMP(2,1+2);
    printf("%d/n", r);

 return 0;
}

//-----------------------------------------------

$gcc -O2 -S macro_disasm.c
GCC優化編譯後:

 .file "macro_disasm.c"
gcc2_compiled.:
___gnu_compiled_c:
.text
LC0:
 .ascii "%d/12/0"
 .p2align 2
.globl _main
_main:
 pushl %ebp
 movl %esp,%ebp
 subl $8,%esp
 addl $-8,%esp
 pushl $-1 ; 居然直接在彙編代碼中顯示結果-1
 pushl $LC0
 call _printf
 xorl %eax,%eax
 movl %ebp,%esp
 popl %ebp
 ret

 

$gcc -S macro_disasm.c

不用優化編譯:

 .file "macro_disasm.c"
gcc2_compiled.:
___gnu_compiled_c:
.text
LC0:
 .ascii "%d/12/0"
 .p2align 2
.globl _main
_main:
 pushl %ebp
 movl %esp,%ebp
 subl $24,%esp
 movl $-1,-4(%ebp) ; 仍然直接將結果-1放入內存
 addl $-8,%esp
 movl -4(%ebp),%eax ; 讀出結果-1,進棧
 pushl %eax
 pushl $LC0
 call _printf
 addl $16,%esp
 xorl %eax,%eax
 jmp L2
 .p2align 4,,7
L2:
 movl %ebp,%esp
 popl %ebp
 ret


宏在編譯過程中就被編譯器直接替換,不生成額外的執行代碼。
 

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