X86匯編語言學(xué)習(xí)_第1頁
X86匯編語言學(xué)習(xí)_第2頁
X86匯編語言學(xué)習(xí)_第3頁
X86匯編語言學(xué)習(xí)_第4頁
X86匯編語言學(xué)習(xí)_第5頁
已閱讀5頁,還剩29頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、X86匯編語言學(xué)習(xí)手記X86匯編編語言學(xué)學(xué)習(xí)手記記(1)1. 編譯譯環(huán)境 OSS: SSolaariss 9 X866 Coompiilerr: ggcc 3.33.2 Linnkerr: SSolaariss Liink Ediitorrs 55.x Debbug Toool: mdbb Edditoor: vi 注:關(guān)于編編譯環(huán)境境的安裝裝和設(shè)置置,可以以參考文文章:SSolaariss 上的的開發(fā)環(huán)環(huán)境安裝裝及設(shè)置置。 mdbb是Soolarris提提供的kkernnel debbug工工具,這這里用它它做反匯匯編和匯匯編語言言調(diào)試工工具。 如果果在Liinuxx平臺(tái)可可以用ggdb進(jìn)進(jìn)

2、行反匯匯編和調(diào)調(diào)試。 2. 最簡(jiǎn)簡(jiǎn)C代碼碼分析 為為簡(jiǎn)化問問題,來來分析一一下最簡(jiǎn)簡(jiǎn)的c代代碼生成成的匯編編代碼: # vii teest11.c iint maiin() retturnn 0; 編譯譯該程序序,產(chǎn)生生二進(jìn)制制文件: # gccc ttestt1.cc -oo teest11 # fiile tesst1 tesst1: ELLF 332-bbit LSBB exxecuutabble 803386 Verrsioon 11, ddynaamiccallly llinkked, noot sstriippeed ttestt1是一一個(gè)ELLF格式式32位位小端(Litttle

3、e Enndiaan)的的可執(zhí)行行文件,動(dòng)動(dòng)態(tài)鏈接接并且符符號(hào)表沒沒有去除除。 這正是是Uniix/LLinuux平臺(tái)臺(tái)典型的的可執(zhí)行行文件格格式。 用mmdb反反匯編可可以觀察察生成的的匯編代代碼: # mddb ttestt1 Loaadinng mmoduuless: liibc.so.1 maain:diis ; 反反匯編mmainn函數(shù),mmdb的的命令一一般格式式為 :diss mmainn: ppushhl %eebp ; eebp寄寄存器內(nèi)內(nèi)容壓棧棧,即保保存maain函函數(shù)的上上級(jí)調(diào)用用函數(shù)的的棧基地地址 maiin+11: movvl %espp,%eebp ; espp值

4、賦給給ebpp,設(shè)置置maiin函數(shù)數(shù)的?;?maiin+33: ssubll $88,%eesp maain+6: anddl $0 xff0,%espp mmainn+9: moovl $0,%eaax maiin+00 xe: ssubll %eeax,%essp maiin+00 x100: movvl $0,%eaxx ; 設(shè)置函函數(shù)返回回值0 maain+0 x115: leeavee ; 將eebp值值賦給eesp,ppop先先前棧內(nèi)內(nèi)的上級(jí)級(jí)函數(shù)棧棧的基地地址給eebp,恢恢復(fù)原棧棧基址 maain+0 x116: reet ; maain函函數(shù)返回回,回到到上級(jí)調(diào)調(diào)用 注

5、注:這里里得到的的匯編語語言語法法格式與與Inttel的的手冊(cè)有有很大不不同,UUnixx/Liinuxx采用AAT&TT匯編格格式作為為匯編語語言的語語法格式式 如果果想了解解AT&T匯編編可以參參考文章章:Liinuxx ATT&T 匯編語語言開發(fā)發(fā)指南 問問題:誰誰調(diào)用了了 maain函函數(shù)? 在在C語言言的層面面來看,mmainn函數(shù)是是一個(gè)程程序的起起始入口口點(diǎn),而而實(shí)際上上,ELLF可執(zhí)執(zhí)行文件件的入口口點(diǎn)并不不是maain而而是_sstarrt。 mmdb也也可以反反匯編_staart: _sttartt:ddis ;從從_sttartt 的地地址開始始反匯編編 _staart:

6、 ppushhl $00 _staart+2: ppushhl $00 _staart+4: mmovll %eesp,%ebbp _sttartt+6: pusshl %edxx _staart+7: mmovll $00 x8005044b0,%eaax _sttartt+0 xxc: tesstl %eaxx,%eeax _sstarrt+00 xe: jee +0 xxf _sstarrt+00 x100: puushll $0 xx805504bb0 _sttartt+0 xx15: calll -0 x775 _sstarrt+00 x1aa: adddl $4,%essp _st

7、tartt+0 xx1d: movvl $0 x8806007100,%eeax _sstarrt+00 x222: teestll %eaax,%eaxx _staart+0 x224: jje +77 _staart+0 x226: ccalll -00 x866 _sttartt+0 xx2b: pusshl $0 x8805006cdd _staart+0 x330: ccalll -00 x900 _sttartt+0 xx35: movvl +8(%ebpp),%eaxx _staart+0 x338: lleall +00 x100(%eebp,%eaax,44),%edxx _

8、staart+0 x33c: mmovll %eedx,0 x8806008044 _staart+0 x442: aandll $00 xf00,%eesp _sstarrt+00 x455: suubl $4,%essp _sttartt+0 xx48: pusshl %edxx _staart+0 x449: lleall +00 xc(%ebbp),%eddx _sttartt+0 xx4c: pusshl %edxx _staart+0 x44d: ppushhl %eeax _sstarrt+00 x4ee: caall +0 xx1522 _sstarrt+00 x533: ca

9、all -0 xxa3 _staart+0 x558: caall +0 xxfb ;在這這里調(diào)用用了maain函函數(shù) _sttartt+0 xx5d: adddl $0 xcc,%eesp _sstarrt+00 x600: puushll %eaax _sttartt+0 xx61: calll -0 xaa1 _staart+0 x666: ppushhl $00 _staart+0 x668: mmovll $11,%eeax _sstarrt+00 x6dd: lccalll $7,$0 _sstarrt+00 x744: hllt 問問題:為為什么用用EAXX寄存器器保存函函數(shù)返回

10、回值? 實(shí)際際上IAA32并并沒有規(guī)規(guī)定用哪哪個(gè)寄存存器來保保存返回回值。但但如果反反匯編SSolaariss/Liinuxx的二進(jìn)進(jìn)制文件件,就會(huì)會(huì)發(fā)現(xiàn),都都用EAAX保存存函數(shù)返返回值。 這不不是偶然然現(xiàn)象,是是操作系系統(tǒng)的AABI(Apppliccatiion Binnaryy Innterrfacce)來來決定的的。 Sollariis/LLinuux操作作系統(tǒng)的的ABII就是SSyteem VV ABBI。 概概念:SSFP (Sttackk Frramee Poointter) 棧框框架指針針 正正確理解解SFPP必須了了解: IIA322 的棧棧的概念念 CPUU 中332位寄寄

11、存器EESP/EBPP的作用用 PUSSH/PPOP 指令是是如何影影響棧的的 CALLL/RRET/LEAAVE 等指令令是如何何影響棧棧的 如如我們所所知: 1)IA332的棧棧是用來來存放臨臨時(shí)數(shù)據(jù)據(jù),而且且是LIIFO,即即后進(jìn)先先出的。棧棧的增長(zhǎng)長(zhǎng)方向是是從高地地址向低低地址增增長(zhǎng),按按字節(jié)為為單位編編址。 2) EBBP是棧棧基址的的指針,永永遠(yuǎn)指向向棧底(高高地址),EESP是是棧指針針,永遠(yuǎn)遠(yuǎn)指向棧棧頂(低低地址)。 3) PUUSH一一個(gè)loong型型數(shù)據(jù)時(shí)時(shí),以字字節(jié)為單單位將數(shù)數(shù)據(jù)壓入入棧,從從高到低低按字節(jié)節(jié)依次將將數(shù)據(jù)存存入ESSP-11、ESSP-22、ESSP-3

12、3、ESSP-44的地址址單元。 4) POOP一個(gè)個(gè)lonng型數(shù)數(shù)據(jù),過過程與PPUSHH相反,依依次將EESP-4、EESP-3、EESP-2、EESP-1從棧棧內(nèi)彈出出,放入入一個(gè)332位寄寄存器。 5) CAALL指指令用來來調(diào)用一一個(gè)函數(shù)數(shù)或過程程,此時(shí)時(shí),下一一條指令令地址會(huì)會(huì)被壓入入堆棧,以以備返回回時(shí)能恢恢復(fù)執(zhí)行行下條指指令。 6) REET指令令用來從從一個(gè)函函數(shù)或過過程返回回,之前前CALLL保存存的下條條指令地地址會(huì)從從棧內(nèi)彈彈出到EEIP寄寄存器中中,程序序轉(zhuǎn)到CCALLL之前下下條指令令處執(zhí)行行 77) EENTEER是建建立當(dāng)前前函數(shù)的的??蚣芗埽聪嘞喈?dāng)于以以下

13、兩條條指令: pusshl %ebpp movvl %espp,%eebp 8) LEEAVEE是釋放放當(dāng)前函函數(shù)或者者過程的的??蚣芗?,即相相當(dāng)于以以下兩條條指令: movvl eebp espp poppl ebpp 如如果反匯匯編一個(gè)個(gè)函數(shù),很很多時(shí)候候會(huì)在函函數(shù)進(jìn)入入和返回回處,發(fā)發(fā)現(xiàn)有類類似如下下形式的的匯編語語句: pusshl %ebpp ; eebp寄寄存器內(nèi)內(nèi)容壓棧棧,即保保存maain函函數(shù)的上上級(jí)調(diào)用用函數(shù)的的?;氐刂?moovl %essp,%ebpp ; espp值賦給給ebpp,設(shè)置置 maain函函數(shù)的棧?;?. ; 以上上兩條指指令相當(dāng)當(dāng)于 eenteer

14、00,0 . leeavee ; 將ebbp值賦賦給essp,ppop先先前棧內(nèi)內(nèi)的上級(jí)級(jí)函數(shù)棧棧的基地地址給eebp,恢恢復(fù)原棧?;?rret ; maain函函數(shù)返回回,回到到上級(jí)調(diào)調(diào)用 這這些語句句就是用用來創(chuàng)建建和釋放放一個(gè)函函數(shù)或者者過程的的??蚣芗艿?。 原來來編譯器器會(huì)自動(dòng)動(dòng)在函數(shù)數(shù)入口和和出口處處插入創(chuàng)創(chuàng)建和釋釋放棧框框架的語語句。 函數(shù)數(shù)被調(diào)用用時(shí): 1) EIIP/EEBP成成為新函函數(shù)棧的的邊界 函數(shù)數(shù)被調(diào)用用時(shí),返返回時(shí)的的EIPP首先被被壓入堆堆棧;創(chuàng)創(chuàng)建??蚩蚣軙r(shí),上上級(jí)函數(shù)數(shù)棧的EEBP被被壓入堆堆棧,與與EIPP一道行行成新函函數(shù)??蚩蚣艿倪呥吔?2) EBPP

15、成為棧??蚣苤钢羔楽FFP,用用來指示示新函數(shù)數(shù)棧的邊邊界 棧框架架建立后后,EBBP指向向的棧的的內(nèi)容就就是上一一級(jí)函數(shù)數(shù)棧的EEBP,可可以想象象,通過過EBPP就可以以把層層層調(diào)用函函數(shù)的棧棧都回朔朔遍歷一一遍,調(diào)調(diào)試器就就是利用用這個(gè)特特性實(shí)現(xiàn)現(xiàn) baackttracce功能能的 3) ESPP總是作作為棧指指針指向向棧頂,用用來分配配??臻g間 棧棧分配空空間給函函數(shù)局部部變量時(shí)時(shí)的語句句通常就就是給EESP減減去一個(gè)個(gè)常數(shù)值值,例如如,分配配一個(gè)整整型數(shù)據(jù)據(jù)就是 ESPP-4 4) 函數(shù)數(shù)的參數(shù)數(shù)傳遞和和局部變變量訪問問可以通通過SFFP即EEBP來來實(shí)現(xiàn) 由由于棧框框架指針針永遠(yuǎn)指

16、指向當(dāng)前前函數(shù)的的?;氐刂罚瑓?shù)和局局部變量量訪問通通常為如如下形式式: +88+xxx(%eebp) ; 函函數(shù)入口口參數(shù)的的的訪問問 -xxx(%eebp) ; 函數(shù)數(shù)局部變變量訪問問 假如函函數(shù)A調(diào)調(diào)用函數(shù)數(shù)B,函函數(shù)B調(diào)調(diào)用函數(shù)數(shù)C ,則則函數(shù)棧棧框架及及調(diào)用關(guān)關(guān)系如下下圖所示示: b:77711001bbbb0下圖有有點(diǎn)亂,因因此刪去去部分內(nèi)內(nèi)容,要要看原圖圖可參考考我的bblogg/bb:77711001bbbb0 +-+- 高地地址 | EIIP (上級(jí)函函數(shù)返回回地址) | +-+ | EBBP (上級(jí)函函數(shù)的EEBP) | +-+ | LLocaal VVariiabll

17、es | | . | +-+ | Argg n(函數(shù)BB的第nn個(gè)參數(shù)數(shù)) | +-+ | Arrg .(函數(shù)數(shù)B的第第.個(gè)參參數(shù)) | +-+ | Arrg 11(函數(shù)數(shù)B的第第1個(gè)參參數(shù)) | +-+ | Argg 0(函數(shù)BB的第00個(gè)參數(shù)數(shù)) | +-+ EIPP (AA函數(shù)的的返回地地址) | +-+ | EBPP (AA函數(shù)的的EBPP) | +-+ | Loocall Vaariaablees | | . | +-+ | Arrg nn(函數(shù)數(shù)C的第第n個(gè)參參數(shù)) | +-+ | AArg .(函函數(shù)C的的第.個(gè)個(gè)參數(shù)) | +-+ | Arrg 11(函數(shù)數(shù)C的第第1個(gè)參參數(shù))

18、 | +-+ | Argg 0(函數(shù)CC的第00個(gè)參數(shù)數(shù)) | +-+ | EIIP (B函數(shù)數(shù)的返回回地址) | +-+ | EBBP (B函數(shù)數(shù)的EBBP) | +-+ | Loocall Vaariaablees | | . | +-+- 低地地址 圖 1-11 再再分析ttestt1反匯匯編結(jié)果果中剩余余部分語語句的含含義: # mdbb teest11 LLoaddingg moodulles: libbc.sso.11 maiin:diss ; 反反匯編mmainn函數(shù) maain: puushll %ebbp maain+1: moovl %essp,%ebpp ; 創(chuàng)建建Sta

19、ack Fraame(??蚣芗? maiin+33: ssubll $88,%eesp ; 通通過ESSP-88來分配配8字節(jié)節(jié)堆棧空空間 maiin+66: aandll $00 xf00,%eesp ; 使使棧地址址16字字節(jié)對(duì)齊齊 mmainn+9: moovl $0,%eaax ; 無意意義 maiin+00 xe: ssubll %eeax,%essp ; 無無意義 maain+0 x110: moovl $0,%eaax ; 設(shè)置置maiin函數(shù)數(shù)返回值值 mmainn+0 xx15: lleavve ; 撤撤銷Sttackk Frramee(??蚩蚣? maain+0 x116:

20、 reet ; maain 函數(shù)返返回 以以下兩句句似乎是是沒有意意義的,果果真是這這樣嗎? movvl $0,%eaxx suubl %eeax,%essp 用用gccc的O22級(jí)優(yōu)化化來重新新編譯ttestt1.cc: # ggcc -O22 teest11.c -o tesst1 # mdbb teest11 maain:diis maiin: ppushhl %eebp maain+1: movvl %espp,%eebp maain+3: subbl $8,%espp mmainn+6: anndl $0 xxf0,%essp maiin+99: xxorll %eeax,%eaax

21、 ; 設(shè)置mmainn返回值值,使用用xorrl異或或指令來來使eaax為00 mmainn+0 xxb: leeavee mmainn+0 xxc: reet 新的的反匯編編結(jié)果比比最初的的結(jié)果要要簡(jiǎn)潔一一些,果果然之前前被認(rèn)為為無用的的語句被被優(yōu)化掉掉了,進(jìn)進(jìn)一步驗(yàn)驗(yàn)證了之之前的猜猜測(cè)。 提示示:編譯譯器產(chǎn)生生的某些些語句可可能在程程序?qū)嶋H際語義上上沒有用用處,可可以用優(yōu)優(yōu)化選項(xiàng)項(xiàng)去掉這這些語句句。 問問題:為為什么用用xorrl來設(shè)設(shè)置eaax的值值? 注意到到優(yōu)化后后的代碼碼中,eeax返返回值的的設(shè)置由由 moovl $0,%eaax 變變?yōu)?xxorll %eeax,%eaax ,

22、這這是因?yàn)闉镮A332指令令中,xxorll比moovl有有更高的的運(yùn)行速速度。 概概念:SStacck aaliggnedd 棧對(duì)對(duì)齊 那么,以以下語句句到底是是和作用用呢? ssubll $88,%eesp anndl $0 xxf0,%essp ; 通通過anndl使使低4位位為0,保保證棧地地址166字節(jié)對(duì)對(duì)齊 表表面來看看,這條條語句最最直接的的后果是是使ESSP的地地址后44位為00,即116字節(jié)節(jié)對(duì)齊,那那么為什什么這么么做呢? 原原來,IIA322 系列列CPUU的一些些指令分分別在44、8、116字節(jié)節(jié)對(duì)齊時(shí)時(shí)會(huì)有更更快的運(yùn)運(yùn)行速度度,因此此gccc編譯器器為提高高生成代代碼

23、在IIA322上的運(yùn)運(yùn)行速度度,默認(rèn)認(rèn)對(duì)產(chǎn)生生的代碼碼進(jìn)行116字節(jié)節(jié)對(duì)齊 anddl $0 xff0,%espp 的意意義很明明顯,那那么 ssubll $88,%eesp 呢,是是必須的的嗎? 這里里假設(shè)在在進(jìn)入mmainn函數(shù)之之前,棧棧是166字節(jié)對(duì)對(duì)齊的話話,那么么,進(jìn)入入maiin函數(shù)數(shù)后,EEIP和和EBPP被壓入入堆棧后后,棧地地址最末末4位二二進(jìn)制位位必定是是 10000,eesp -8則則恰好使使后4位位地址二二進(jìn)制位位為00000。看看來,這這也是為為保證棧棧16字字節(jié)對(duì)齊齊的。 如如果查一一下gccc的手手冊(cè),就就會(huì)發(fā)現(xiàn)現(xiàn)關(guān)于棧棧對(duì)齊的的參數(shù)設(shè)設(shè)置: -mmpreefe

24、rrredd-sttackk-boounddaryy=n ; 希希望棧按按照2的的n次的的字節(jié)邊邊界對(duì)齊齊, nn的取值值范圍是是2-112 默默認(rèn)情況況下,nn是等于于4的,也也就是說說,默認(rèn)認(rèn)情況下下,gccc是116字節(jié)節(jié)對(duì)齊,以以適應(yīng)IIA322大多數(shù)數(shù)指令的的要求。 讓讓我們利利用-mmpreeferrredd-sttackk-boounddaryy=2來來去除棧棧對(duì)齊指指令: # gccc -mprrefeerreed-sstacck-bbounndarry=22 teest11.c -o tesst1 mmainn:ddis maain: puushll %ebbp maiin+

25、11: movvl %espp,%eebp maain+3: moovl $0,%eaax maiin+88: leaave maain+9: reet 可可以看到到,棧對(duì)對(duì)齊指令令沒有了了,因?yàn)闉?,IAA32的的棧本身身就是44字節(jié)對(duì)對(duì)齊的,不不需要用用額外指指令進(jìn)行行對(duì)齊。 那么么,??蚩蚣苤羔樶楽FPP是不是是必須的的呢? # gccc -mmpreeferrredd-sttackk-boounddaryy=2 -foomitt-frramee-poointter tesst1.c -o ttestt maiin:diss mmainn: mmovll $00,%eeax maain+5

26、: reet 由由此可知知,-ffomiit-fframme-ppoinnterr 可以以去除SSFP。 問題:去除SSFP后后有什么么缺點(diǎn)呢呢? 11)增加加調(diào)式難難度 由于于SFPP在調(diào)試試器baackttracce的指指令中被被使用到到,因此此沒有SSFP該該調(diào)試指指令就無無法使用用。 2)降降低匯編編代碼可可讀性 函函數(shù)參數(shù)數(shù)和局部部變量的的訪問,在在沒有eebp的的情況下下,都只只能通過過+xxx(essp)的的方式訪訪問,而而很難區(qū)區(qū)分兩種種方式,降降低了程程序的可可讀性。 問題:去除SSFP有有什么優(yōu)優(yōu)點(diǎn)呢? 1)節(jié)省棧??臻g 2)減少建建立和撤撤銷??蚩蚣艿闹钢噶詈螅?jiǎn)簡(jiǎn)化了代

27、代碼 3)使使ebpp空閑出出來,使使之作為為通用寄寄存器使使用,增增加通用用寄存器器的數(shù)量量 44)以上上3點(diǎn)使使得程序序運(yùn)行速速度更快快 概概念:CCalllingg Coonveentiion 調(diào)用用約定和和 ABBI (Apppliccatiion Binnaryy Innterrfacce) 應(yīng)用程程序二進(jìn)進(jìn)制接口口 函數(shù)數(shù)如何找找到它的的參數(shù)? 函數(shù)如如何返回回結(jié)果? 函數(shù)在在哪里存存放局部部變量? 那一個(gè)個(gè)硬件寄寄存器是是起始空空間? 那那一個(gè)硬硬件寄存存器必須須預(yù)先保保留? CCalllingg Coonveentiion 調(diào)用用約定對(duì)對(duì)以上問問題作出出了規(guī)定定。Caallii

28、ng Connvenntioon也是是ABII的一部部分。 因此此,遵守守相同AABI規(guī)規(guī)范的操操作系統(tǒng)統(tǒng),使其其相互間間實(shí)現(xiàn)二二進(jìn)制代代碼的互互操作成成為了可可能。 例如如:由于于Sollariis、LLinuux都遵遵守Syysteem VV的ABBI,SSolaariss 100就提供供了直接接運(yùn)行LLinuux二進(jìn)進(jìn)制程序序的功能能。 詳見文文章:關(guān)關(guān)注: Sollariis 110的110大新新變化 3. 小結(jié) 本文文通過最最簡(jiǎn)的CC程序,引引入以下下概念: SFPP 棧框框架指針針 Staack aliigneed 棧棧對(duì)齊 CCalllingg Coonveentiion 調(diào)用用

29、約定 和 AABI (Apppliicattionn Biinarry IInteerfaace) 應(yīng)用用程序二二進(jìn)制接接口 今后,將將通過進(jìn)進(jìn)一步的的實(shí)驗(yàn),來來深入了了解這些些概念。通通過掌握握這些概概念,使使在匯編編級(jí)調(diào)試試程序產(chǎn)產(chǎn)生的ccoree duump、掌掌握C語語言高級(jí)級(jí)調(diào)試技技巧成為為了可能能。X86匯編編語言學(xué)學(xué)習(xí)手記記(2)這是作者在在學(xué)習(xí)XX86匯匯編過程程中的學(xué)學(xué)習(xí)筆記記,難免免有錯(cuò)誤誤和疏漏漏之處,歡歡迎指正正。作者者將隨時(shí)時(shí)修改錯(cuò)錯(cuò)誤并將將新的版版本發(fā)布布在自己己的Bllog站站點(diǎn)上。嚴(yán)嚴(yán)格說來來,本篇篇文檔更更側(cè)重于于C語言言和C編編譯器方方面的知知識(shí),如如果涉及

30、及到基本本的匯編編語言的的內(nèi)容,可可以參考考相關(guān)文文檔。 自X886 匯匯編語言言學(xué)習(xí)手手記(11)在作作者的BBlogg上發(fā)布布以來,得得到了很很多網(wǎng)友友的肯定定和鼓勵(lì)勵(lì),并且且還有熱熱心網(wǎng)友友指出了了其中的的錯(cuò)誤,b:bbea666dddae00作者者已經(jīng)將將文檔中中已發(fā)現(xiàn)現(xiàn)的錯(cuò)誤誤修正后后更新在在Bloog上。/b:beaa66dddaee0 上上一篇文文章通過過分析一一個(gè)最簡(jiǎn)簡(jiǎn)的C程程序,引引出了以以下概念念: Sttackk Frramee 棧框框架 和和 SFFP 棧棧框架指指針 Sttackk allignned 棧對(duì)齊齊 Calllinng CConvventtionn 調(diào)調(diào)用

31、約定定 和 ABII (AAppllicaatioon BBinaary Intterffacee) 應(yīng)應(yīng)用程序序二進(jìn)制制接口 本章章中,將將通過進(jìn)進(jìn)一步的的實(shí)驗(yàn),來來深入了了解這些些概念。如如果還不不了解這這些概念念,可以以參考 X866匯編語語言學(xué)習(xí)習(xí)手記(1)。 1. 局部變變量的棧棧分配 上上篇文章章已經(jīng)分分析過一一個(gè)最簡(jiǎn)簡(jiǎn)的C程程序, 下面面我們分分析一下下C編譯譯器如何何處理局局部變量量的分配配,為此此先給出出如下程程序: #vi tesst2.c iint maiin() intt i; intt j=2; ii=3; i=+i; retturnn i+j; 編編譯該程程序,產(chǎn)產(chǎn)

32、生二進(jìn)進(jìn)制文件件,并利利用mddb來觀觀察程序序運(yùn)行中中的sttackk的狀態(tài)態(tài): #gccc ttestt2.cc -oo teest22 #mdbb teest22 LLoaddingg moodulles: libbc.sso.11 maiin:diss mmainn: pusshl %ebpp mmainn+1: movvl %espp,%eebp ; mmainn至maain+1,創(chuàng)創(chuàng)建Sttackk Frramee mmainn+3: subbl $8,%espp ; 為為局部變變量i,j分配配??臻g間,并保保證棧116字節(jié)節(jié)對(duì)齊 maain+6: aandll $00 xf00,

33、%eesp maain+9: mmovll $00,%eeax maain+0 xee: ssubll %eeax,%essp ; maain+6至mmainn+0 xxe,再再次保證證棧166字節(jié)對(duì)對(duì)齊 maain+0 x110: mmovll $22,-88(%eebp) ; 初始始化局部部變量jj的值為為2 maiin+00 x177: moovl $3,-4(%ebbp) ; 給局部部變量ii賦值為為3 maiin+00 x1ee: leeal -4(%ebbp),%eaax ; 將局部部變量ii的地址址裝入到到EAXX寄存器器中 maiin+00 x211: inncl (%eeax

34、) ; i+ mmainn+0 xx23: movvl -8(%ebpp),%eaxx ; 將將j的值值裝入EEAX maain+0 x226: aaddll -44(%eebp),%eeax ; i+j并將將結(jié)果存存入EAAX,作作為返回回值 maiin+00 x299: leeavee ; 撤銷銷Staack Fraame mmainn+0 xx2a: rett ; maiin函數(shù)數(shù)返回 maain+0 x110:bb ; 在在地址 maiin+00 x100處設(shè)置置斷點(diǎn) maiin+00 x1ee:b ; 在mmainn+0 xx1e設(shè)設(shè)置斷點(diǎn)點(diǎn) maain+0 x229:bb ; 在在

35、maiin+00 x1ee設(shè)置斷斷點(diǎn) mmainn+0 xx2a:b ; 在maain+0 x11e設(shè)置置斷點(diǎn) 下面面的mddb的44個(gè)命令令在一行行輸入,中中間用分分號(hào)間隔隔開,命命令的含含義在注注釋中給給出: :r;essp,110/nnap;ebbp=XX;eeax=X ; 運(yùn)行行程序(:r 命令) mmdb: sttop at maiin+00 x100 ; 以以ESPP寄存器器為起始始地址,指指定格式式輸出116字節(jié)節(jié)的棧內(nèi)內(nèi)容(espp,100/naap 命命令) mddb: tarrgett sttoppped at: ; 在最后后輸出EEBP和和EAXX寄存器器的值(ebbp=

36、XX 命令令 和 :cc;eesp,10/napp;eebp=X; :c;essp,110/nnap;ebbp=XX; :cc;eesp,10/napp;eebp=X; :s;essp,110/nnap;ebbp=XX; 通通過mddb對(duì)程程序運(yùn)行行時(shí)的寄寄存器和和棧的觀觀察和分分析,可可以得出出局部變變量在棧棧中的訪訪問和分分配及釋釋放方式式: 1.局部變變量的分分配,可可以通過過espp減去所所需字節(jié)節(jié)數(shù) ssubll $88,%eesp 22.局部部變量的的釋放,可可以通過過leaave指指令 leaave 3.局局部變量量的訪問問,可以以通過eebp減減去偏移移量 mmovll -88

37、(%eebp),%eeax adddl -4(%ebpp),%eaxx 問問題:當(dāng)當(dāng)存在22個(gè)以上上的局部部變量時(shí)時(shí),如何何進(jìn)行棧棧對(duì)齊? 在在上篇文文章中,提提到suubl $8,%essp語句句除了分分配??湛臻g外,還還有一個(gè)個(gè)作用就就是棧對(duì)對(duì)齊。那那么本例例中,由由于i和和j正好好是8字字節(jié),那那么如果果存在22個(gè)以上上的局部部變量時(shí)時(shí),如何何同時(shí)滿滿足空間間分配和和棧對(duì)齊齊呢? 2. 兩個(gè)個(gè)以上的的局部變變量的棧棧分配 在在之前的的C程序序中,增增加局部部變量定定義k,程程序如下下: # vvi ttestt3.cc iint maiin() intt i, j=2, k=44; i=

38、3; ii=+i; kk=i+j+kk; reeturrn kk; 編編譯該程程序后,用用mdbb反匯編編得出如如下結(jié)果果: # ggcc tesst3.c -o ttestt3 # mdbb teest33 LLoaddingg moodulles: libbc.sso.11 maiin:diss mmainn: puushll %ebbp maiin+11: mmovll %eesp,%ebbp ; maiin至mmainn+1,創(chuàng)創(chuàng)建Sttackk Frramee mmainn+3: subbl $00 x188,%eesp ; 為局局部變量量i,jj,k分分配??湛臻g,并并保證棧棧16

39、字字節(jié)對(duì)齊齊 mmainn+6: anndl $0 xxf0,%essp maiin+99: mmovll $00,%eeax maain+0 xee: subbl %eaxx,%eesp ; maain+6至mmainn+0 xxe,再再次保證證棧166字節(jié)對(duì)對(duì)齊 maiin+00 x100: mmovll $22,-88(%eebp) ; j=22 mmainn+0 xx17: moovl $4,-0 xxc(%ebpp) ; kk=4 maain+0 x11e: movvl $3,-4(%ebpp) ; i=3 maiin+00 x255: lleall -44(%eebp),%eeax

40、 ; 將i的的地址裝裝入到EEAX maain+0 x228: inccl (%eaax) ; i+ maiin+00 x2aa: mmovll -88(%eebp),%eeax ; 將j的的值裝入入到 EEAX maain+0 x22d: movvl -4(%ebpp),%edxx ; 將ii的值裝裝入到 EDXX mmainn+0 xx30: adddl %eaax,%edxx ; jj+i,結(jié)結(jié)果存入入EDXX mmainn+0 xx32: leeal -0 xxc(%ebpp),%eaxx ; 將將k的地地址裝入入到EAAX maiin+00 x355: aaddll %eedx,(%

41、eeax) ; i+jj+k,結(jié)結(jié)果存入入地址eebp-0 xcc即k中中 mmainn+0 xx37: moovl -0 xxc(%ebpp),%eaxx ; 將將k的值值裝入EEAX,作作為返回回值 maiin+00 x3aa: lleavve ; 撤銷SStacck FFramme maiin+00 x3bb: rret ; maiin函數(shù)數(shù)返回 問問題:為為什么33個(gè)變量量分配了了0 x118字節(jié)節(jié)的??湛臻g? 在22個(gè)變量量的時(shí)候候,分配配??臻g間的指令令是:ssubll $88,%eesp 而在在3個(gè)局局部變量量的時(shí)候候,分配配??臻g間的指令令是:ssubll $00 x188,%eesp 3個(gè)個(gè)整型變變量只需需要0 xxc字節(jié)節(jié),為何何實(shí)際上上分配了了0 x118字節(jié)節(jié)呢? 答案案就是:保持116字節(jié)節(jié)棧對(duì)齊齊。 在在X866 匯編編語言學(xué)學(xué)習(xí)手記記(1)里,已已經(jīng)說明明過gccc默認(rèn)認(rèn)的編譯譯是要116字節(jié)節(jié)棧對(duì)齊齊的,ssubll $88,%eesp會(huì)會(huì)使棧116字節(jié)節(jié)對(duì)齊,而而8字節(jié)節(jié)空間只只能滿足足2個(gè)局局部變量量,如果果再分配配4字節(jié)節(jié)滿足第第3個(gè)局局部變量量的話,那那棧地址址就不再再16字字

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論