X86匯編語言學習_第1頁
X86匯編語言學習_第2頁
X86匯編語言學習_第3頁
X86匯編語言學習_第4頁
X86匯編語言學習_第5頁
已閱讀5頁,還剩29頁未讀 繼續免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

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

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

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

4、賦給給ebpp,設置置maiin函數數的棧基基址 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 ; 設置函函數返回回值0 maain+0 x115: leeavee ; 將eebp值值賦給eesp,ppop先先前棧內內的上級級函數棧棧的基地地址給eebp,恢恢復原棧棧基址 maain+0 x116: reet ; maain函函數返回回,回到到上級調調用 注

5、注:這里里得到的的匯編語語言語法法格式與與Inttel的的手冊有有很大不不同,UUnixx/Liinuxx采用AAT&TT匯編格格式作為為匯編語語言的語語法格式式 如果果想了解解AT&T匯編編可以參參考文章章:Liinuxx ATT&T 匯編語語言開發發指南 問問題:誰誰調用了了 maain函函數? 在在C語言言的層面面來看,mmainn函數是是一個程程序的起起始入口口點,而而實際上上,ELLF可執執行文件件的入口口點并不不是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 ;在這這里調用用了maain函函數 _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寄存器器保存函函數返回

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

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

12、3、ESSP-44的地址址單元。 4) POOP一個個lonng型數數據,過過程與PPUSHH相反,依依次將EESP-4、EESP-3、EESP-2、EESP-1從棧棧內彈出出,放入入一個332位寄寄存器。 5) CAALL指指令用來來調用一一個函數數或過程程,此時時,下一一條指令令地址會會被壓入入堆棧,以以備返回回時能恢恢復執行行下條指指令。 6) REET指令令用來從從一個函函數或過過程返回回,之前前CALLL保存存的下條條指令地地址會從從棧內彈彈出到EEIP寄寄存器中中,程序序轉到CCALLL之前下下條指令令處執行行 77) EENTEER是建建立當前前函數的的棧框架架,即相相當于以以下

13、兩條條指令: pusshl %ebpp movvl %espp,%eebp 8) LEEAVEE是釋放放當前函函數或者者過程的的棧框架架,即相相當于以以下兩條條指令: movvl eebp espp poppl ebpp 如如果反匯匯編一個個函數,很很多時候候會在函函數進入入和返回回處,發發現有類類似如下下形式的的匯編語語句: pusshl %ebpp ; eebp寄寄存器內內容壓棧棧,即保保存maain函函數的上上級調用用函數的的棧基地地址 moovl %essp,%ebpp ; espp值賦給給ebpp,設置置 maain函函數的棧棧基址 . ; 以上上兩條指指令相當當于 eenteer

14、00,0 . leeavee ; 將ebbp值賦賦給essp,ppop先先前棧內內的上級級函數棧棧的基地地址給eebp,恢恢復原棧棧基址 rret ; maain函函數返回回,回到到上級調調用 這這些語句句就是用用來創建建和釋放放一個函函數或者者過程的的棧框架架的。 原來來編譯器器會自動動在函數數入口和和出口處處插入創創建和釋釋放棧框框架的語語句。 函數數被調用用時: 1) EIIP/EEBP成成為新函函數棧的的邊界 函數數被調用用時,返返回時的的EIPP首先被被壓入堆堆棧;創創建棧框框架時,上上級函數數棧的EEBP被被壓入堆堆棧,與與EIPP一道行行成新函函數棧框框架的邊邊界 2) EBPP

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

16、指向當前前函數的的棧基地地址,參參數和局局部變量量訪問通通常為如如下形式式: +88+xxx(%eebp) ; 函函數入口口參數的的的訪問問 -xxx(%eebp) ; 函數數局部變變量訪問問 假如函函數A調調用函數數B,函函數B調調用函數數C ,則則函數棧棧框架及及調用關關系如下下圖所示示: b:77711001bbbb0下圖有有點亂,因因此刪去去部分內內容,要要看原圖圖可參考考我的bblogg/bb:77711001bbbb0 +-+- 高地地址 | EIIP (上級函函數返回回地址) | +-+ | EBBP (上級函函數的EEBP) | +-+ | LLocaal VVariiabll

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

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

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

20、 reet ; maain 函數返返回 以以下兩句句似乎是是沒有意意義的,果果真是這這樣嗎? movvl $0,%eaxx suubl %eeax,%essp 用用gccc的O22級優化化來重新新編譯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、 ; 設置mmainn返回值值,使用用xorrl異或或指令來來使eaax為00 mmainn+0 xxb: leeavee mmainn+0 xxc: reet 新的的反匯編編結果比比最初的的結果要要簡潔一一些,果果然之前前被認為為無用的的語句被被優化掉掉了,進進一步驗驗證了之之前的猜猜測。 提示示:編譯譯器產生生的某些些語句可可能在程程序實際際語義上上沒有用用處,可可以用優優化選項項去掉這這些語句句。 問問題:為為什么用用xorrl來設設置eaax的值值? 注意到到優化后后的代碼碼中,eeax返返回值的的設置由由 moovl $0,%eaax 變變為 xxorll %eeax,%eaax ,

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

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

24、rrredd-sttackk-boounddaryy=n ; 希希望棧按按照2的的n次的的字節邊邊界對齊齊, nn的取值值范圍是是2-112 默默認情況況下,nn是等于于4的,也也就是說說,默認認情況下下,gccc是116字節節對齊,以以適應IIA322大多數數指令的的要求。 讓讓我們利利用-mmpreeferrredd-sttackk-boounddaryy=2來來去除棧棧對齊指指令: # 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 可可以看到到,棧對對齊指令令沒有了了,因為為,IAA32的的棧本身身就是44字節對對齊的,不不需要用用額外指指令進行行對齊。 那么么,棧框框架指針針SFPP是不是是必須的的呢? # 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后后有什么么缺點呢呢? 11)增加加調式難難度 由于于SFPP在調試試器baackttracce的指指令中被被使用到到,因此此沒有SSFP該該調試指指令就無無法使用用。 2)降降低匯編編代碼可可讀性 函函數參數數和局部部變量的的訪問,在在沒有eebp的的情況下下,都只只能通過過+xxx(essp)的的方式訪訪問,而而很難區區分兩種種方式,降降低了程程序的可可讀性。 問題:去除SSFP有有什么優優點呢? 1)節省棧棧空間 2)減少建建立和撤撤銷棧框框架的指指令后,簡簡化了代

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

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

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

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

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

32、生二進進制文件件,并利利用mddb來觀觀察程序序運行中中的sttackk的狀態態: #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,創創建Sttackk Frramee mmainn+3: subbl $8,%espp ; 為為局部變變量i,j分配配棧空間間,并保保證棧116字節節對齊 maain+6: aandll $00 xf00,

33、%eesp maain+9: mmovll $00,%eeax maain+0 xee: ssubll %eeax,%essp ; maain+6至mmainn+0 xxe,再再次保證證棧166字節對對齊 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并將將結果存存入EAAX,作作為返回回值 maiin+00 x299: leeavee ; 撤銷銷Staack Fraame mmainn+0 xx2a: rett ; maiin函數數返回 maain+0 x110:bb ; 在在地址 maiin+00 x100處設置置斷點 maiin+00 x1ee:b ; 在mmainn+0 xx1e設設置斷點點 maain+0 x229:bb ; 在在

35、maiin+00 x1ee設置斷斷點 mmainn+0 xx2a:b ; 在maain+0 x11e設置置斷點 下面面的mddb的44個命令令在一行行輸入,中中間用分分號間隔隔開,命命令的含含義在注注釋中給給出: :r;essp,110/nnap;ebbp=XX;eeax=X ; 運行行程序(:r 命令) mmdb: sttop at maiin+00 x100 ; 以以ESPP寄存器器為起始始地址,指指定格式式輸出116字節節的棧內內容(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對程程序運行行時的寄寄存器和和棧的觀觀察和分分析,可可以得出出局部變變量在棧棧中的訪訪問和分分配及釋釋放方式式: 1.局部變變量的分分配,可可以通過過espp減去所所需字節節數 ssubll $88,%eesp 22.局部部變量的的釋放,可可以通過過leaave指指令 leaave 3.局局部變量量的訪問問,可以以通過eebp減減去偏移移量 mmovll -88

37、(%eebp),%eeax adddl -4(%ebpp),%eaxx 問問題:當當存在22個以上上的局部部變量時時,如何何進行棧棧對齊? 在在上篇文文章中,提提到suubl $8,%essp語句句除了分分配棧空空間外,還還有一個個作用就就是棧對對齊。那那么本例例中,由由于i和和j正好好是8字字節,那那么如果果存在22個以上上的局部部變量時時,如何何同時滿滿足空間間分配和和棧對齊齊呢? 2. 兩個個以上的的局部變變量的棧棧分配 在在之前的的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反匯編編得出如如下結果果: # 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,創創建Sttackk Frramee mmainn+3: subbl $00 x188,%eesp ; 為局局部變量量i,jj,k分分配棧空空間,并并保證棧棧16

39、字字節對齊齊 mmainn+6: anndl $0 xxf0,%essp maiin+99: mmovll $00,%eeax maain+0 xee: subbl %eaxx,%eesp ; maain+6至mmainn+0 xxe,再再次保證證棧166字節對對齊 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,結結果存入入EDXX mmainn+0 xx32: leeal -0 xxc(%ebpp),%eaxx ; 將將k的地地址裝入入到EAAX maiin+00 x355: aaddll %eedx,(%

41、eeax) ; i+jj+k,結結果存入入地址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函數數返回 問問題:為為什么33個變量量分配了了0 x118字節節的棧空空間? 在22個變量量的時候候,分配配棧空間間的指令令是:ssubll $88,%eesp 而在在3個局局部變量量的時候候,分配配棧空間間的指令令是:ssubll $00 x188,%eesp 3個個整型變變量只需需要0 xxc字節節,為何何實際上上分配了了0 x118字節節呢? 答案案就是:保持116字節節棧對齊齊。 在在X866 匯編編語言學學習手記記(1)里,已已經說明明過gccc默認認的編譯譯是要116字節節棧對齊齊的,ssubll $88,%eesp會會使棧116字節節對齊,而而8字節節空間只只能滿足足2個局局部變量量,如果果再分配配4字節節滿足第第3個局局部變量量的話,那那棧地址址就不再再16字字

溫馨提示

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

評論

0/150

提交評論