freepeople性欧美熟妇, 色戒完整版无删减158分钟hd, 无码精品国产vα在线观看DVD, 丰满少妇伦精品无码专区在线观看,艾栗栗与纹身男宾馆3p50分钟,国产AV片在线观看,黑人与美女高潮,18岁女RAPPERDISSSUBS,国产手机在机看影片

正文內(nèi)容

x86匯編語言學(xué)習(xí)(已修改)

2025-04-19 07:00 本頁面
 

【正文】 X86匯編語言學(xué)習(xí)手記X86匯編語言學(xué)習(xí)手記(1)1. 編譯環(huán)境 OS: Solaris 9 X86 Compiler: gcc Linker: Solaris Link Editors Debug Tool: mdb Editor: vi 注:關(guān)于編譯環(huán)境的安裝和設(shè)置,可以參考文章:Solaris 上的開發(fā)環(huán)境安裝及設(shè)置。 mdb是Solaris提供的kernel debug工具,這里用它做反匯編和匯編語言調(diào)試工具。 如果在Linux平臺(tái)可以用gdb進(jìn)行反匯編和調(diào)試。 2. 最簡(jiǎn)C代碼分析 為簡(jiǎn)化問題,來分析一下最簡(jiǎn)的c代碼生成的匯編代碼: vi int main() { return 0。 } 編譯該程序,產(chǎn)生二進(jìn)制文件: gcc o test1 file test1 test1: ELF 32bit LSB executable 80386 Version 1, dynamically linked, not stripped test1是一個(gè)ELF格式32位小端(Little Endian)的可執(zhí)行文件,動(dòng)態(tài)鏈接并且符號(hào)表沒有去除。 這正是Unix/Linux平臺(tái)典型的可執(zhí)行文件格式。 用mdb反匯編可以觀察生成的匯編代碼: mdb test1 Loading modules: [ ] main::dis 。 反匯編main函數(shù),mdb的命令一般格式為 地址::dis main: pushl %ebp 。 ebp寄存器內(nèi)容壓棧,即保存main函數(shù)的上級(jí)調(diào)用函數(shù)的?;刂? main+1: movl %esp,%ebp 。 esp值賦給ebp,設(shè)置main函數(shù)的棧基址 main+3: subl $8,%esp main+6: andl $0xf0,%esp main+9: movl $0,%eax main+0xe: subl %eax,%esp main+0x10: movl $0,%eax 。 設(shè)置函數(shù)返回值0 main+0x15: leave 。 將ebp值賦給esp,pop先前棧內(nèi)的上級(jí)函數(shù)棧的基地址給ebp,恢復(fù)原?;? main+0x16: ret 。 main函數(shù)返回,回到上級(jí)調(diào)用 注:這里得到的匯編語言語法格式與Intel的手冊(cè)有很大不同,Unix/Linux采用ATamp。T匯編格式作為匯編語言的語法格式 如果想了解ATamp。T匯編可以參考文章:Linux ATamp。T 匯編語言開發(fā)指南 問題:誰調(diào)用了 main函數(shù)? 在C語言的層面來看,main函數(shù)是一個(gè)程序的起始入口點(diǎn),而實(shí)際上,ELF可執(zhí)行文件的入口點(diǎn)并不是main而是_start。 mdb也可以反匯編_start: _start::dis 。從_start 的地址開始反匯編 _start: pushl $0 _start+2: pushl $0 _start+4: movl %esp,%ebp _start+6: pushl %edx _start+7: movl $0x80504b0,%eax _start+0xc: testl %eax,%eax _start+0xe: je +0xf _start+0x1d _start+0x10: pushl $0x80504b0 _start+0x15: call 0x75 atexit _start+0x1a: addl $4,%esp _start+0x1d: movl $0x8060710,%eax _start+0x22: testl %eax,%eax _start+0x24: je +7 _start+0x2b _start+0x26: call 0x86 atexit _start+0x2b: pushl $0x80506cd _start+0x30: call 0x90 atexit _start+0x35: movl +8(%ebp),%eax _start+0x38: leal +0x10(%ebp,%eax,4),%edx _start+0x3c: movl %edx,0x8060804 _start+0x42: andl $0xf0,%esp _start+0x45: subl $4,%esp _start+0x48: pushl %edx _start+0x49: leal +0xc(%ebp),%edx _start+0x4c: pushl %edx _start+0x4d: pushl %eax _start+0x4e: call +0x152 _init _start+0x53: call 0xa3 __fpstart _start+0x58: call +0xfb main 。在這里調(diào)用了main函數(shù) _start+0x5d: addl $0xc,%esp _start+0x60: pushl %eax _start+0x61: call 0xa1 exit _start+0x66: pushl $0 _start+0x68: movl $1,%eax _start+0x6d: lcall $7,$0 _start+0x74: hlt 問題:為什么用EAX寄存器保存函數(shù)返回值? 實(shí)際上IA32并沒有規(guī)定用哪個(gè)寄存器來保存返回值。但如果反匯編Solaris/Linux的二進(jìn)制文件,就會(huì)發(fā)現(xiàn),都用EAX保存函數(shù)返回值。 這不是偶然現(xiàn)象,是操作系統(tǒng)的ABI(Application Binary Interface)來決定的。 Solaris/Linux操作系統(tǒng)的ABI就是Sytem V ABI。 概念:SFP (Stack Frame Pointer) ??蚣苤羔? 正確理解SFP必須了解: IA32 的棧的概念 CPU 中32位寄存器ESP/EBP的作用 PUSH/POP 指令是如何影響棧的 CALL/RET/LEAVE 等指令是如何影響棧的 如我們所知: 1)IA32的棧是用來存放臨時(shí)數(shù)據(jù),而且是LIFO,即后進(jìn)先出的。棧的增長(zhǎng)方向是從高地址向低地址增長(zhǎng),按字節(jié)為單位編址。 2) EBP是棧基址的指針,永遠(yuǎn)指向棧底(高地址),ESP是棧指針,永遠(yuǎn)指向棧頂(低地址)。 3) PUSH一個(gè)long型數(shù)據(jù)時(shí),以字節(jié)為單位將數(shù)據(jù)壓入棧,從高到低按字節(jié)依次將數(shù)據(jù)存入ESPESPESPESP4的地址單元。 4) POP一個(gè)long型數(shù)據(jù),過程與PUSH相反,依次將ESPESPESPESP1從棧內(nèi)彈出,放入一個(gè)32位寄存器。 5) CALL指令用來調(diào)用一個(gè)函數(shù)或過程,此時(shí),下一條指令地址會(huì)被壓入堆棧,以備返回時(shí)能恢復(fù)執(zhí)行下條指令。 6) RET指令用來從一個(gè)函數(shù)或過程返回,之前CALL保存的下條指令地址會(huì)從棧內(nèi)彈出到EIP寄存器中,程序轉(zhuǎn)到CALL之前下條指令處執(zhí)行 7) ENTER是建立當(dāng)前函數(shù)的棧框架,即相當(dāng)于以下兩條指令: pushl %ebp movl %esp,%ebp 8) LEAVE是釋放當(dāng)前函數(shù)或者過程的棧框架,即相當(dāng)于以下兩條指令: movl ebp esp popl ebp 如果反匯編一個(gè)函數(shù),很多時(shí)候會(huì)在函數(shù)進(jìn)入和返回處,發(fā)現(xiàn)有類似如下形式的匯編語句: pushl %ebp 。 ebp寄存器內(nèi)容壓棧,即保存main函數(shù)的上級(jí)調(diào)用函數(shù)的?;刂? movl %esp,%ebp 。 esp值賦給ebp,設(shè)置 main函數(shù)的棧基址 ........... 。 以上兩條指令相當(dāng)于 enter 0,0 ........... leave160
點(diǎn)擊復(fù)制文檔內(nèi)容
公司管理相關(guān)推薦
文庫吧 www.dybbs8.com
公安備案圖鄂ICP備17016276號(hào)-1