wordpress安裝顯示404寧波優(yōu)化網(wǎng)站排名軟件
文章目錄
- 前言
- 1. CPU提供的棧機(jī)制
- 2. push指令
- 3. 問題
- 4. 問題的分析與解答
- 5. pop指令
- 結(jié)語
前言
📌
匯編語言是很多相關(guān)課程(如數(shù)據(jù)結(jié)構(gòu)、操作系統(tǒng)、微機(jī)原理)的重要基礎(chǔ)。但僅僅從課程的角度出發(fā)就太片面了,其實(shí)學(xué)習(xí)匯編語言可以深入理解計(jì)算機(jī)底層工作原理,提升代碼效率,尤其在嵌入式系統(tǒng)和性能優(yōu)化方面有重要作用。此外,它在逆向工程和安全領(lǐng)域不可或缺,幫助分析軟件運(yùn)行機(jī)制并增強(qiáng)漏洞修復(fù)能力。
本專欄的匯編語言學(xué)習(xí)章節(jié)主要是依據(jù)王爽老師的《匯編語言》來寫的,和書中一樣為了使學(xué)習(xí)的過程容易展開,我們采用以8086CPU為中央處理器的PC機(jī)來進(jìn)行學(xué)習(xí)。
1. CPU提供的棧機(jī)制
現(xiàn)今的CPU中都有棧的設(shè)計(jì),8086CPU也不例外。8086CPU提供相關(guān)的指令來以棧的方式訪問內(nèi)存空間。這意味著,在基于8086CPU編程的時(shí)候,可以將一段內(nèi)存當(dāng)作棧來使用。
8086CPU提供入和出棧指令,最基本的兩個(gè)是PUSH(入棧)和POP(出棧)。
比如,push ax 表示將寄存器ax中的數(shù)據(jù)送入棧中,pop ax 表示從棧頂取出數(shù)據(jù)送入 ax。
8086CPU的入棧和出棧操作都是以字為單位進(jìn)行的。
舉例說明:
下面舉例說明,我們可以將10000H-1000FH這段內(nèi)存當(dāng)作棧來使用。下圖描述了下面一段指令的執(zhí)行過程。
注意,字型數(shù)據(jù)用兩個(gè)單元存放,高地址單元存放高8位,低地址單元存放低8位
大家看到上圖所描述的 push 和 pop指令的執(zhí)行過程,是否有一些疑惑?
總結(jié)一下,大概是這兩個(gè)問題。
- 其一,我們將10000H-1000FH這段內(nèi)存當(dāng)作來使用,CPU執(zhí)行push和pop令時(shí),將對(duì)這段空間按照棧的后進(jìn)先出的規(guī)則進(jìn)行訪問。但是,一個(gè)重要的問題是,CPU如何知道10000H-1000FH這段空間被當(dāng)作棧來使用?
- 其二,push ax等入棧指令執(zhí)行時(shí),要將寄存器中的內(nèi)容放入當(dāng)前棧頂單元的上方,成為新的棧頂元素;pop ax等指令執(zhí)行時(shí),要從棧頂單元中取出數(shù)據(jù),送入寄存器中。顯然,push、pop在執(zhí)行的時(shí)候,必須知道哪個(gè)單元是棧頂單元,可是,如何知道呢?
這不禁讓我們想起之前另外一個(gè)討論過的問題,就是,CPU如何知道當(dāng)前要執(zhí)行的指令所在的位置?我們現(xiàn)在知道答案,那就是CS、IP中存放著當(dāng)前指令的段地址和偏移地址。
現(xiàn)在的問題是:CPU如何知道棧頂?shù)奈恢?#xff1f;顯然,也應(yīng)該有相應(yīng)的寄存器來存放棧頂?shù)牡刂?#xff0c;8086CPU中,有兩個(gè)寄存器,段存器SS和寄存器SP,棧頂?shù)亩蔚刂反娣旁赟S中,偏移地址存放在SP中。任意時(shí)刻,SS:SP指向棧頂元素。push指令和pop指令執(zhí)行時(shí),CPU從SS和SP中得到棧頂?shù)牡刂贰?/p>
2. push指令
現(xiàn)在,我們可以完整地描述push和pop指令的功能了,例如push ax。
push ax的執(zhí)行,由以下兩步完成。
(1)SP=SP-2,SS:SP指向當(dāng)前棧頂前面的單元,以當(dāng)前棧頂前面的單元為新的棧頂
(2)將ax中的內(nèi)容送入 SS:SP指向的內(nèi)存單元處,SS:SP 此時(shí)指向新棧頂。
下圖描述了8086CPU 對(duì) push 指令的執(zhí)行過程。
從圖中我們可以看出,8086CPU中,入棧時(shí),棧頂從高地址向低地址方向增長(zhǎng)。
3. 問題
如果將10000H-1000FH這段空間當(dāng)作,初始狀態(tài)棧是空的,此時(shí),SS=1000H,SP=?
思考后看分析。
4. 問題的分析與解答
SP=0010H,如下圖所示。
我們將10000H-1000FH這間當(dāng)作棧段,SS=1000H,空間大小為16字節(jié),最底部的字單元地址為1000:000E。任意時(shí)刻,SS:SP指向頂,當(dāng)中只有一個(gè)元素的時(shí)候,SS=1000H,SP=000EH。
棧為空,就相當(dāng)于中唯一的元素出棧,出后SP=SP+2,SP原來為000EH,加2后SP=10H,所以,當(dāng)為空的時(shí)候,SS=1000H,SP=10H。
換一個(gè)角度看,任意時(shí)刻,SS:SP指向棧頂元素,當(dāng)棧為空的時(shí)候,棧中沒有元素,也就不存在棧頂元素,所以SS:SP只能指向棧的最底部單元下面的單元,該單元的偏移地址為棧最底部的字單元的偏移地址+2,棧最底部字單元的地址為1000:000E,所以??諘r(shí),SP=0010H。
5. pop指令
接下來,我們描述pop指令的功能,例如pop ax。
pop ax的執(zhí)行過程和 push ax 剛好相反,由以下兩步完成。
(1)將SS:SP指向的內(nèi)存單元處的數(shù)據(jù)送入ax中
(2)SP=SP+2,SS:SP指向當(dāng)前棧頂下面的單元,以當(dāng)前頂下面的單元為新的棧頂
下圖描述了8086CPU對(duì)pop指令的執(zhí)行過程。
?注意
上圖中,出棧后,SS:SP指向新的頂1000EH,pop操作前的頂元素1000CH處的2266H依然存在,但是,它已不在棧中。當(dāng)再次執(zhí)行push等入指令后SS:SP移至1000CH,并在里面寫入新的數(shù)據(jù),它將被覆蓋。
結(jié)語
今天的分享到這里就結(jié)束啦!如果覺得文章還不錯(cuò)的話,可以三連支持一下。
也可以點(diǎn)點(diǎn)關(guān)注,避免以后找不到我哦!
Crossoads主頁還有很多有趣的文章,歡迎小伙伴們前去點(diǎn)評(píng),您的支持就是作者前進(jìn)的動(dòng)力!