日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) >

Intel汇编程序设计-高级过程(上)

發(fā)布時(shí)間:2025/6/17 55 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Intel汇编程序设计-高级过程(上) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

第八章?高級(jí)過(guò)程

8.1?簡(jiǎn)介

本章主要講:

堆棧框架

變量作用域和生存期

對(duì)戰(zhàn)參數(shù)的類型

通過(guò)傳遞值或者傳遞引用來(lái)傳遞參數(shù)

在堆棧上創(chuàng)建和初始化局部變量

遞歸

編寫多模塊程序

內(nèi)存模型和語(yǔ)言關(guān)鍵字

注意關(guān)鍵詞:

子過(guò)程=函數(shù)=方法(因不同語(yǔ)言導(dǎo)致名字不統(tǒng)一)

8.2堆棧框架(很重要)

? ? 堆棧框架(stack?frame)也稱活動(dòng)記錄(activation?record),它是為傳遞的參數(shù)、子例程的返回地址、局部變量和保存的寄存器保留的堆棧空間。堆棧框架是按一下步驟創(chuàng)建的:

1.如果有傳遞的參數(shù),則壓入堆棧。

2.子歷程被調(diào)用,字壘成的返回地址壓入堆棧。

3.子例程開始時(shí),EBP被壓入堆棧。

4.EBP設(shè)為ESP的值,從這時(shí)開始,EBP就被座位尋址所有子例程參數(shù)的基址指針使用了。

5.如果任何寄存器需要保存,則亞茹堆棧。

? ? 堆棧框架的結(jié)構(gòu)手程序的內(nèi)存模式及參數(shù)傳遞約定直接影響。

8.2.1?堆棧參數(shù)

? ? 有兩種基本類型的子例程參數(shù):寄存器參數(shù)和堆棧參數(shù)。Irvine32Irvine16庫(kù)使用寄存器參數(shù),本節(jié)講述如何聲明和使用堆棧參數(shù)。

? ? 被調(diào)用的子例程訪問(wèn)調(diào)用子例程時(shí)亞茹堆棧的參數(shù)。使用寄存器參數(shù)可以優(yōu)化程序的執(zhí)行速度,但是遺憾的是,這樣可能會(huì)造成代碼的混亂,因?yàn)橛行┘拇嫫髟谘b入?yún)?shù)之前必須首先保存。例如,調(diào)用DumpMem時(shí)就是這種情況:


Pushad

Mov?esi,OFFSET?array???????????;起始偏移地址

Mov?ecx,LENGTHOF?array???????;大小

Mov?ebx,TYPE?array????????????;雙字格式

Call?DumpMem????????????????;顯示內(nèi)存內(nèi)容?

Popad

?

? ? 另外一種更靈活的方式是堆棧參數(shù),在調(diào)用子例程之前,參數(shù)首先壓入堆棧。例如,假設(shè)DumpMem使用堆棧參數(shù),那么可以使用下面的代碼進(jìn)行調(diào)用:

Push?TYPE?array

Push?LENGTHOF?array

Push?PFFSET?array

Call?DumpMem

? ? 在進(jìn)行子例程調(diào)用時(shí)在堆棧上壓入了兩類參數(shù):

? ? ? 值參數(shù)(變量和常量的值)

? ? ? 引用參數(shù)(地址)

?

堆棧參數(shù)的訪問(wèn)(C/C++

? ? 在調(diào)用函數(shù)時(shí),C/C++程序使用標(biāo)準(zhǔn)的方法初始化和訪問(wèn)參數(shù)。C/C++中的函數(shù)以序言(prologue)開始,序言部分的代碼保存了EBP寄存器,并使EBP指向當(dāng)時(shí)堆棧的頂部,函數(shù)還有可能把一些寄存器壓棧,這些寄存器的值將在函數(shù)返回的時(shí)候恢復(fù)。函數(shù)以收尾(epilogue)代碼結(jié)束,在這部分代碼中,EBP寄存器被恢復(fù),RET指令從函數(shù)返回。

例子AddTwo

C:

Int?AddTwo(int?x?,int?y){

????Return?x?+?y;

}

對(duì)應(yīng)匯編:

?

AddTwo?PROC

Push?ebp

Mov?ebp,esp??????????;堆棧框架的基址

Mov?eax,[ebp+12]?????;第二個(gè)參數(shù)

Mov?eax,[ebp+8]??????;第一個(gè)參數(shù)

Pop??ebp???????

Ret

AddTwo?ENDP


自己用vs2012看了下反匯編(DeBug模式)

調(diào)用部分:

?

函數(shù)部分


堆棧的清理

? ? 在子例程返回時(shí),必須要有某種方法清除堆棧上的參數(shù),否則就會(huì)導(dǎo)致內(nèi)存泄漏以及堆棧的破壞。假設(shè)main中調(diào)用AddTwo的語(yǔ)句如下:

Push?5

Push?5

Call?AddTwo

下面是從調(diào)用返回后堆棧的示意圖:

?

? ? 如果沒(méi)有清理,那么函數(shù)結(jié)束的時(shí)候就會(huì)從棧里拿出來(lái)一個(gè)地址,然后跳轉(zhuǎn)過(guò)去。那么上面就直接跳轉(zhuǎn)到存儲(chǔ)5的地 址了,這樣就發(fā)生問(wèn)題了。

? ?對(duì)于這個(gè)問(wèn)題,一種簡(jiǎn)單的解決方法是在CALL指令后使用一條ADD指令給ESP加上一個(gè)值,以使ESP指向正確的返回地址:

Example1?PROC

????Push??5

????Push??6

????Call??AddTwo

????Add??esp,8

????Ret

Example1?ENDP

? ? 這實(shí)際上也是C++使用的一種方法。

????STDCALL調(diào)用約定(Calling?Convention:處理堆棧清理問(wèn)題的另一種方法是使用STDCALL調(diào)用約定,可以在AddTwo過(guò)程中的RET指令后提供一個(gè)整數(shù)參數(shù)以修復(fù)ESP的值,這個(gè)整數(shù)值必須等于堆棧參數(shù)小號(hào)的堆棧空間字節(jié)數(shù)。

? ? 大體是下面這樣的姿勢(shì):

AddTwo?PROC

Push??ebp

Mov??ebp,esp

Mov??eax,[ebp+12]

Add??eax,[ebp+8]

Pop?ebp

Ret?8

AddTwo?ENDP

? ? 這樣一來(lái),上面堆棧清理問(wèn)題就簡(jiǎn)化了:誰(shuí)應(yīng)該對(duì)清理堆棧負(fù)責(zé)?是調(diào)用子例程的代碼,還是子例程本身?這兩種方式都有各自的優(yōu)缺點(diǎn):STDCALL減少了為子例程調(diào)用生成代碼數(shù)量(只有一條指令)并且能夠確保調(diào)用者永遠(yuǎn)不會(huì)忘記清理堆棧;另一方面,C調(diào)用約定允許子例程生命可變數(shù)目的參數(shù),由調(diào)用者決定要傳遞多少參數(shù)。例子之一是printf函數(shù),這種類型的,清理堆棧的職責(zé)職能留給調(diào)用者了。

? ? 通過(guò)堆棧傳遞8位和16位的參數(shù)

? ? 在保護(hù)模式下傳遞參數(shù)時(shí),最好使用32位的操作數(shù),雖然可以砸IDUI站上壓入16位的操作數(shù),但這樣會(huì)似的ESP無(wú)法對(duì)其在雙字地址邊界上,由此可能會(huì)導(dǎo)致發(fā)生頁(yè)故障,程序的性能也能會(huì)降低。因此在傳遞8位或16位對(duì)扎你參數(shù)時(shí),應(yīng)把它擴(kuò)展到32位在壓棧。

So需要把一些小寬度參數(shù)擴(kuò)展成32位的:movzx?eax,word1

那如果是大于32位的怎么辦?:這個(gè)我們可以分開傳遞,先傳32位,再傳32...

?

USER操作符對(duì)堆棧的影響

之前應(yīng)該說(shuō)過(guò)USER,它可以幫助保存和恢復(fù)一些寄存器的值。例如:

MySub1?PROC?USES?ecx?,edx

Ret

MySub1?ENDP

下面是匯編時(shí)產(chǎn)生的代碼:

Push?ecx

Push?edx

Pop??edx

Pop??ecx

Ret


? ? 假設(shè)在MySub2中把USES和堆棧參數(shù)一起使用,我們預(yù)期第一個(gè)參數(shù)在堆棧位置EBP+8處:

MySub2?PROC?USES?ecx?,edx

Push?ebp

Mov?ebp,esp

Mov?eax,[ebp+8]

Pop?ebp

Ret?4

MySub2?ENDP

下面是生成的匯編代碼
push?ecx

Push?edx

Push?ebp

Mov?ebp,esp

Mov?eax,dword?ptr[ebp+8]??;錯(cuò)誤的位置!

Pop?ebp

Pop?edx

Pop?ecx

Ret?4

總結(jié)

以上是生活随笔為你收集整理的Intel汇编程序设计-高级过程(上)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。