?? 8.html
字號(hào):
0x80483e2 : leave<br>0x80483e3 : ret<br>...<br>0x80483ef : nop<br>End of assembler dump.<br>(gdb) disass hi<br>Dump of assembler code for function hi:<br>0x80483c8 : push %ebp<br>0x80483c9 : mov %esp,%ebp<br>0x80483cb : push $0x8048440<br>0x80483d0 : call 0x8048308<br>0x80483d5 : leave<br>0x80483d6 : ret<br>0x80483d7 : nop<br>End of assembler dump.<br>由于程序比較簡(jiǎn)單,再優(yōu)化也沒(méi)有好優(yōu)化的了,所以跟-O出來(lái)的一樣。<p><br><center><A HREF="#Content">[目錄](méi)</A></center><hr><br><A NAME="I202" ID="I202"></A><center><b><font size=+2>-fomit-frame-pointer 編譯選項(xiàng)</font></b></center><br>★ -fomit-frame-pointer 編譯選項(xiàng)<br>-fomit-frame-pointer<br> Don't keep the frame pointer in a register for functions<br> that don't need one. This avoids the instructions to save,<br> set up and restore frame pointers; it also makes an extra<br> register available in many functions. It also makes<br> debugging impossible on most machines.<p> 忽略幀指針。這樣在程序就不需要保存,安裝,和恢復(fù)ebp了。這樣ebp也就是一個(gè)free的register了,在函數(shù)中就可以隨便使用了。<p>[alert7@redhat62 alert7]$ gcc -fomit-frame-pointer -o test test.c<br>[alert7@redhat62 alert7]$ wc -c test<br> 11773 test<br>[alert7@redhat62 alert7]$ gdb -q test<br>(gdb) disass main<br>Dump of assembler code for function main:<br>0x80483e0 : call 0x80483d0<br>0x80483e5 : xor %eax,%eax<br>0x80483e7 : jmp 0x80483f0<br>0x80483e9 : lea 0x0(%esi,1),%esi<br>0x80483f0 : ret<br>....<br>End of assembler dump.<br>(gdb) disass hi<br>Dump of assembler code for function hi:<br>0x80483d0 : push $0x8048450<br>0x80483d5 : call 0x8048308<br>0x80483da : add $0x4,%esp<br>0x80483dd : ret<br>0x80483de : mov %esi,%esi<br>End of assembler dump.<br>在main()和hi()中都去掉了以下指令<br>push %ebp<br>mov %esp,%ebp//這兩條指令安裝<br>leave//這條指令恢復(fù)<br>來(lái)看看部分的內(nèi)存映象<br> (內(nèi)存高址)<br> +--------+<br> |bffffbc4| argv的地址(即argv[0]的地址)<br> 0xbffffb84 +--------+<br> |00000001| argc的值<br> 0xbffffb80 +--------+<br> |400309cb|main的返回地址<br> 0xbffffb7c +--------+<br> |080483e5| hi()的返回地址<br> 0xbffffb78 +--------+<br> |08048450| "hi"字符串的地址<br> 0xbffffb74 +--------+<br> | ...... |<br> (內(nèi)存低址)<br>沒(méi)有保存上層執(zhí)行環(huán)境的ebp.<p><p><center><A HREF="#Content">[目錄](méi)</A></center><hr><br><A NAME="I203" ID="I203"></A><center><b><font size=+2>-fomit-frame-pointer && -O2</font></b></center><br>★ -fomit-frame-pointer && -O2<br>-fomit-frame-pointer編譯選項(xiàng)去掉了<br>push %ebp<br>mov %esp,%ebp//這兩條指令安裝<br>leave//這條指令恢復(fù)<br>-O2編譯選項(xiàng)去掉了<br>add $0x4,%esp<br>兩個(gè)加起來(lái)會(huì)不會(huì)這四條指令一起去掉,從而使stack不平衡呢?<br>[alert7@redhat62 alert7]$ gcc -fomit-frame-pointer -O2 -o test test.c<br>[alert7@redhat62 alert7]$ wc -c test<br> 11741 test<br>[alert7@redhat62 alert7]$ gdb -q test<br>(gdb) disass main<br>Dump of assembler code for function main:<br>0x80483d8 : call 0x80483c8<br>0x80483dd : xor %eax,%eax<br>0x80483df : ret<br>End of assembler dump.<br>(gdb) disass hi<br>Dump of assembler code for function hi:<br>0x80483c8 : push $0x8048430<br>0x80483cd : call 0x8048308<br>0x80483d2 : add $0x4,%esp<br>0x80483d5 : ret<br>0x80483d6 : mov %esi,%esi<br>End of assembler dump.<br>來(lái)看看部分的內(nèi)存映象<br> (內(nèi)存高址)<br> +--------+<br> |bffffbc4| argv的地址(即argv[0]的地址)<br> 0xbffffb84 +--------+<br> |00000001| argc的值<br> 0xbffffb80 +--------+<br> |400309cb|main的返回地址<br> 0xbffffb7c +--------+<br> |080483dd| hi()的返回地址<br> 0xbffffb78 +--------+<br> |08048430| "hi"字符串的地址<br> 0xbffffb74 +--------+<br> | ...... |<br> (內(nèi)存低址)<br>此時(shí)就沒(méi)有把a(bǔ)dd $0x4,%esp優(yōu)化掉,如果優(yōu)化掉的話(huà),整個(gè)stack就<br>會(huì)變的不平衡,從而會(huì)導(dǎo)致程序出錯(cuò)。<p><p><center><A HREF="#Content">[目錄](méi)</A></center><hr><br><A NAME="I204" ID="I204"></A><center><b><font size=+2>-fPIC 編譯選項(xiàng)</font></b></center><br>★ -fPIC 編譯選項(xiàng)<br>-fPIC If supported for the target machine, emit position-independent<br> code, suitable for dynamic linking,even if branches need large<br> displacements.<p> 產(chǎn)生位置無(wú)關(guān)代碼(PIC),一般創(chuàng)建共享庫(kù)時(shí)用到。<br> 在x86上,PIC的代碼的符號(hào)引用都是通過(guò)ebx進(jìn)行操作的。<p>[alert7@redhat62 alert7]$ gcc -fPIC -o test test.c<br>[alert7@redhat62 alert7]$ wc -c test<br> 11805 test<br>[alert7@redhat62 alert7]$ gdb -q test<br>(gdb) disass main<br>Dump of assembler code for function main:<br>0x80483f8 : push %ebp<br>0x80483f9 : mov %esp,%ebp<br>0x80483fb : push %ebx<br>0x80483fc : call 0x8048401<br>0x8048401 : pop %ebx//取得該指令的地址<br>0x8048402 : add $0x1093,%ebx//此時(shí)ebx里面存放著是GOT表的地址<br>0x8048408 : call 0x80483d0<br>0x804840d : xor %eax,%eax<br>0x804840f : jmp 0x8048411<br>0x8048411 : mov 0xfffffffc(%ebp),%ebx<br>0x8048414 : leave<br>0x8048415 : ret<br>...<br>End of assembler dump.<br>(gdb) disass hi<br>Dump of assembler code for function hi:<br>0x80483d0 : push %ebp<br>0x80483d1 : mov %esp,%ebp<br>0x80483d3 : push %ebx<br>0x80483d4 : call 0x80483d9<br>0x80483d9 : pop %ebx<br>0x80483da : add $0x10bb,%ebx<br>0x80483e0 : lea 0xffffefdc(%ebx),%edx<br>0x80483e6 : mov %edx,%eax<br>0x80483e8 : push %eax<br>0x80483e9 : call 0x8048308<br>0x80483ee : add $0x4,%esp<br>0x80483f1 : mov 0xfffffffc(%ebp),%ebx<br>0x80483f4 : leave<br>0x80483f5 : ret<br>0x80483f6 : mov %esi,%esi<br>End of assembler dump.<br>來(lái)看看部分的內(nèi)存映象<p> (內(nèi)存高址)<br> +--------+<br> |bffffbc4| argv的地址(即argv[0]的地址)<br> 0xbffffb84 +--------+<br> |00000001| argc的值<br> 0xbffffb80 +--------+<br> |400309cb|main的返回地址<br> 0xbffffb7c +--------+ <-- 調(diào)用main函數(shù)前的esp<br> |bffffb98| 調(diào)用main函數(shù)前的ebp<br> 0xbffffb78 +--------+ <-- main函數(shù)的ebp<br> |401081ec| 保存的ebx<br> 0xbffffb74 +--------+<br> |0804840d| (存放過(guò)call 0x8048401的下一條指令地址)<br>
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =