匯編語言存儲及寄存器原理解析
這篇文章主要介紹了匯編語言存儲及寄存器原理解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
字的存儲
一個16位寄存器可以存放一個字(16位)或者一個字節(jié)(8位),當(dāng)存放一個字節(jié)的時候只需要一個內(nèi)存單元(內(nèi)存單元是以字節(jié)為單位的,8位),而存放一個字需要兩個內(nèi)存單元,這樣存放一個字就需要兩個連續(xù)的內(nèi)存單元,這個16位的字,高位存放在高地址,低位存放在低地址。
內(nèi)存地址 | 內(nèi)存數(shù)據(jù) |
---|---|
0 | 20H |
1 | 4EH |
2 | 12H |
3 | 00H |
對于字來說0就是低地址單元,1是高地址單元,則字型數(shù)據(jù)4E20H的低地址位20存放在0號單元,高地址位4E存放在高地址單元,因?yàn)樗钠鹗嫉刂窞?,又可以稱作0地址字單元。
段地址寄存器
通過前面學(xué)過的知識我們可以知道當(dāng)CPU想要對一個內(nèi)存單元進(jìn)行操作時,必須知道它的地址,要知道內(nèi)存單元的地址就要知道它的段地址和偏移地址,在8086 CPU中,DS寄存器就是用來存放段地址的,執(zhí)行指令的時候,CPU會自動讀取DS中的數(shù)據(jù)為內(nèi)存單元的段地址,使用[偏移地址]來表示偏移地址,假設(shè)DS寄存器中此時存放的是1000H,那么mov al,[0]就表示將10000H(物理地址=段地址x16+偏移地址)地址上存放的數(shù)據(jù)存到al中。
如果想要修改DS寄存器中的值,那么直接使用mov指令將數(shù)字存到DS寄存器中是不行的,只能先將值存到一個寄存器中,再使用mov指令將這個寄存器中的值存到DS中,例:
mov bx,1000H mov ds,bx mov ax,[0]
這樣就將地址為10000H處的值存放到ax寄存器中了,也就是將下表中的4E20H存放到ax中。(ax是十六位,一個字,兩個字節(jié))
內(nèi)存地址 | 內(nèi)存數(shù)據(jù) |
---|---|
0 | 20H |
1 | 4EH |
2 | 12H |
3 | 00H |
所以一個內(nèi)存單元地址的確定可以通過段地址DS+[偏移地址]進(jìn)行確定。
add和sub指令
顧名思義,add指令就是用來做加法操作的,sub指令就是用來做減法操作的,例如add ax,8這條指令相當(dāng)于C語言中的ax = ax + 8,sub ax,8相當(dāng)于C語言中的ax = ax - 8。
add和sub指令可以操作的對象有以下幾種形式,以add指令為例:
add 寄存器,數(shù)據(jù) 例如:add ax,8 add 寄存器,寄存器 例如:add ax,bx add 寄存器,內(nèi)存單元 例如:add ax,[0] add 內(nèi)存單元,寄存器 例如:add [0],ax
棧
棧,是一段具有特殊訪問方式的存儲空間,它的存取規(guī)則是先進(jìn)后出,后進(jìn)先出,就像是一個上面沒有蓋的桶,最后放進(jìn)去的東西只能最先取出來。
那么我們怎么知道在連續(xù)的存儲空間中,哪一段是棧,哪一段不是棧,回想一下,CPU是根據(jù)CS、IP兩個寄存器中存放的值判斷當(dāng)前指令存放的位置,根據(jù)DS、偏移地址判斷數(shù)據(jù)存放在哪個內(nèi)存單元,顯然,也會有相應(yīng)的寄存器用來判斷哪一段是棧,在8086 CPU中,通過段寄存器SS和寄存器SP就可以確定棧的位置,棧有棧頂和棧底,棧頂?shù)亩蔚刂反娣旁赟S中,SP用于存放偏移地址,在任意時刻SS:SP指向棧頂元素,它指向的第一個元素可以理解為棧底,以后每存放一個數(shù)據(jù)SS:SP就向上提升,而它所指向的就是棧頂。
PUSH和POP指令
有了棧,那么就可以對棧進(jìn)行存取數(shù)據(jù)的操作,使用的指令時push和pop指令,push指令用于入棧操作,也就是存數(shù)據(jù),pop指令用于出棧,也就是取數(shù)據(jù)。8086 CPU的入棧、出棧操作都是以字為單位。
假設(shè)有如下一段連續(xù)的內(nèi)存單元,此時SS為1000H,SP為000EH,AX為1234H,棧頂為1000EH。
內(nèi)存地址 | 數(shù)據(jù) |
---|---|
1000AH | |
1000BH | |
1000CH | |
1000DH | |
1000EH | |
1000FH |
首先,因?yàn)镾S為1000H,SP為000EH,所以棧頂是指向1000EH位置的:
SS為1000H,SP為000EH,AX為1234H
內(nèi)存地址 | 數(shù)據(jù) |
---|---|
1000AH | |
1000BH | |
1000CH | |
1000DH | |
1000EH | [SS:SP] |
1000FH |
接著我們執(zhí)行入棧操作,將AX(1234H)入棧,使用push ax操作進(jìn)行壓棧。
SS為1000H,SP為000CH,AX為1234H
內(nèi)存地址 | 數(shù)據(jù) |
---|---|
1000AH | |
1000BH | |
1000CH | 34[SS:SP] |
1000DH | 12 |
1000EH | |
1000FH |
此時,新的棧頂就變成了1000CH,接著,我們再將一個立即數(shù)5678H壓入棧中,使用push 5678:
SS為1000H,SP為000AH,AX為1234H。
內(nèi)存地址 | 數(shù)據(jù) |
---|---|
1000AH | 78[SS:SP] |
1000BH | 56 |
1000CH | 34 |
1000DH | 12 |
1000EH | |
1000FH |
這是,棧頂就是1000AH,SS為1000H,SP為000AH。
演示完了入棧,我們再進(jìn)行出棧,使用pop ax操作,將出棧的數(shù)據(jù)放入到ax寄存器中:
SS為1000H,SP為000CH,AX為5678H。
內(nèi)存地址 | 數(shù)據(jù) |
---|---|
1000AH | 78 |
1000BH | 56 |
1000CH | 34[SS:SP] |
1000DH | 12 |
1000EH | |
1000FH |
注意,出棧并不意味著之前寫入內(nèi)存單元的數(shù)據(jù)被刪除了,之前寫入的數(shù)據(jù)還是存在的,只不過它不在棧中了。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
匯編語言指令集之條件轉(zhuǎn)移指令實(shí)現(xiàn)
這篇文章主要介紹了匯編語言指令集之條件轉(zhuǎn)移指令實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-01-01匯編語言指令集學(xué)習(xí)CMPXCHG比較并交換操作指令詳解
這篇文章主要為大家介紹了匯編語言指令集學(xué)習(xí)CMPXCHG比較并交換操作的指令詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步2021-11-11使用匯編語言實(shí)現(xiàn)if else 循環(huán)函數(shù)調(diào)用的具體方法
這篇文章主要介紹了使用匯編語言實(shí)現(xiàn)if else 循環(huán)函數(shù)調(diào)用的具體方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-01-01匯編語言功能用循環(huán)累加實(shí)現(xiàn)乘法
這篇文章主要為大家介紹了匯編語言實(shí)現(xiàn)功能,使用用循環(huán)累加來實(shí)現(xiàn)乘法,文中通過幾個問題實(shí)例分析,來為大家進(jìn)行詳細(xì)講解,有需要的朋友可以借鑒參考下,希望能夠有所幫助2021-11-11UEFI開發(fā)實(shí)戰(zhàn)SlimBootloader中調(diào)用FSP
這篇文章主要為大家介紹了UEFI開發(fā)實(shí)戰(zhàn)SlimBootloader中調(diào)用FSP基礎(chǔ)教程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-06-06