寄存器---汇编学习笔记
第二章 寄存器
2.0 寄存器的緒論
一個(gè)典型的CPU由運(yùn)算器、控制器、寄存器(CPU工作原理)等器件構(gòu)成。內(nèi)部總線實(shí)現(xiàn) CPU 內(nèi)部各個(gè)器件之間的聯(lián)系,外部總線實(shí)現(xiàn)CPU和主板其他器件的聯(lián)系。
在CPU中(下列重要內(nèi)容)
- 運(yùn)算器進(jìn)行信息處理;
- 寄存器進(jìn)行信息存儲(chǔ);
- 控制器控制各個(gè)器件進(jìn)行工作;
- 內(nèi)部總線連接各種器件,在它們之間進(jìn)行數(shù)據(jù)的傳送。
對(duì)于匯編程序員來(lái)說(shuō),CPU中的主要部件是寄存器。寄存器是CPU中與程序員可以用指令讀寫(xiě)的部件。
不同的CPU,寄存器的個(gè)數(shù)、結(jié)構(gòu)是不相同的。
2.1 通用寄存器
8086CPU的所有寄存器都是16位的。
通用寄存器:AX、BX、CX、DX.
一個(gè)16位寄存器的邏輯結(jié)構(gòu):
8086CPU的上一代CPU中的寄存器都是8位的。
為了保證兼容,8086的16bit寄存器可分為兩個(gè)獨(dú)立8bit寄存器
- AX可分為AH和AL.
- BX可分為BH和BL.
- CX可分為CH和CL.
- DX可分為DH和DL.
如圖,AX的高8bit是AH,低8bit是AL:
一個(gè)8bit寄存器所能存儲(chǔ)的數(shù)據(jù)的最大值為255。
2.2 字在寄存器中的存儲(chǔ)
- 字節(jié)(byte):一個(gè)字節(jié)有8個(gè)bit組成,可以存在8位寄存器中。
- 字(word):一個(gè)字由兩個(gè)字節(jié)組成,這兩個(gè)字節(jié)分別稱(chēng)為高位字節(jié)和低位字節(jié)
一個(gè)字可以存在一個(gè)16位寄存器中,這個(gè)字的高位字節(jié)和低位字節(jié)自然就存在這個(gè)寄存器的高8位寄存器和低8位寄存器中。一個(gè)word數(shù)據(jù)20000的例子,如圖:
其中,信息本身是二進(jìn)制數(shù)據(jù),而不是十進(jìn)制數(shù)據(jù),別搞混。
再?gòu)?qiáng)調(diào)一遍,信息本身就是二進(jìn)制數(shù)據(jù)。
2.3 初識(shí)匯編指令
| mov a,b | 將b的數(shù)據(jù)送入a中 | a = b |
| add a,b | 將a+b的數(shù)據(jù)送入a中 | a = a+b |
a代表寄存器,b代表數(shù)據(jù)或者寄存器。
問(wèn)題2.1:指令執(zhí)行后AX中的數(shù)據(jù)是多少?
mov ax,4E20H ;AX=4E20H add ax,1406H ;AX=6226H mov bx,2000H ;BX=2000H add ax,bx ;AX=8226H mov bx,ax ;BX=8226H add ax,bx ;AX=044CH指令執(zhí)行后AX中的數(shù)據(jù)為 004CH。
問(wèn)題2.2:指令執(zhí)行后AX中的數(shù)據(jù)是多少?
指令執(zhí)行后AX中的數(shù)據(jù)為 0158H。
檢測(cè)點(diǎn) 2.1
(1) 寫(xiě)出每條匯編指令執(zhí)行后相關(guān)寄存器中的值。
(2) 只能使用目前學(xué)過(guò)的匯編指令,最多使用4條指令,編程計(jì)算2的4次方。
MOV AX,2 ;AX = 2 ADD AX,AX ;AX = 4 ADD AX,AX ;AX = 8 ADD AX,AX ;AX = 162.4 物理地址
所有的內(nèi)存單元構(gòu)成的存儲(chǔ)空間是一個(gè)一維的線性空間,每一個(gè)內(nèi)存單元在這個(gè)空間中都有一個(gè)唯一的地址,稱(chēng)為物理地址。
CPU通過(guò)地址總線送入存儲(chǔ)器的,必須是一個(gè)內(nèi)存單元的物理地址。
2.5 16位結(jié)構(gòu)的CPU
8080、8085是8位機(jī),8086是16位機(jī)。
16位結(jié)構(gòu)的CPU具有的結(jié)構(gòu)性質(zhì)
- 運(yùn)算器一次最多可以處理16位的數(shù)據(jù);
- 寄存器的最大寬度位16位;
- 寄存器和運(yùn)算器之間的通路為16位。
8086是16位結(jié)構(gòu)的CPU,也就是說(shuō),能夠一次性處理、傳輸、暫時(shí)存儲(chǔ)的信息的最大長(zhǎng)度是16位的。
2.6 8086CPU給出物理地址的方法
8086CPU有20位地址總線,可以傳送20位地址,達(dá)到1MB的尋址能力。8086CPU是16位結(jié)構(gòu),在內(nèi)部一次性處理、傳輸、暫時(shí)存儲(chǔ)的地址為16位。從表面上看CPU只能尋址64KB。
8086CPU采用一種內(nèi)部用兩個(gè)16位地址合成的方法來(lái)形成一個(gè)20位的物理地址。
如圖:
當(dāng)8086CPU要讀寫(xiě)內(nèi)存時(shí)
- CPU中的相關(guān)部件提供兩個(gè)16位的地址,一個(gè)稱(chēng)為段地址,另一個(gè)稱(chēng)為偏移地址;
- 段地址和偏移地址通過(guò)內(nèi)部總線送入一個(gè)稱(chēng)為地址加法器的部件;
- 地址加法器將兩個(gè)16位合成為一個(gè)20位的物理地址;
- 地址加法器通過(guò)內(nèi)部將20位物理地址送入輸入輸出控制電路;
- 輸入輸出控制電路將20位物理地址送上地址總線;
- 20位物理地址被地址總線傳送到存儲(chǔ)器。
地址加法器采用物理地址 = 段地址x16+偏移地址
地址加法器工作過(guò)程(圖中數(shù)據(jù)皆用十六進(jìn)制表示):
由段地址x16引發(fā)的討論
“段地址x16”有一個(gè)更為常用的說(shuō)法是左移4位。
一個(gè)例子:
| 0 | 10B | 2H | 2 |
| 1 | 100B | 4H | 4 |
| 2 | 1000B | 8H | 8 |
| 3 | 10000B | 10H | 16 |
| 4 | 100000B | 20H | 32 |
觀察上面移位數(shù)和各種進(jìn)制數(shù)據(jù)的關(guān)系,我們可以發(fā)現(xiàn):
- 一個(gè)數(shù)據(jù)的 二進(jìn)制形式左移 1位,相當(dāng)于該數(shù)據(jù) 乘以2;
- 一個(gè)數(shù)據(jù)的 二進(jìn)制形式左移 N位,相當(dāng)于該數(shù)據(jù)乘以2的N次方;
- 地址加法器如何完成段地址x16的運(yùn)算?就是將以二進(jìn)制形式存放的段地址左移4位。
不難得出,一個(gè)數(shù)據(jù)的十六進(jìn)制形式左移1位,相當(dāng)于乘以16。
2.7 “段地址x16+偏移地址=物理地址”的本質(zhì)含義
本質(zhì)含義是:CPU在訪問(wèn)內(nèi)存時(shí),用一個(gè)基礎(chǔ)地址(段地址x16)和偏移地址相加,給出內(nèi)存單元的物理地址。(可以理解為從基礎(chǔ)地址出發(fā)+偏移量 = 你要去的目的地)
2.8 段的概念
實(shí)際上,內(nèi)存并沒(méi)有分段,段的劃分來(lái)自于CPU。
我們可以在邏輯上將內(nèi)存“分段”,如圖
編程時(shí),可以根據(jù)需要,將若干個(gè)地址連續(xù)的內(nèi)存單元看做一個(gè)段(注意:段地址一定是16的倍數(shù),一個(gè)段的長(zhǎng)度最大為64KB)。
內(nèi)存單元地址小結(jié)
(1)觀察下面的地址,你有什么發(fā)現(xiàn)?
| 21F60H | 2000H | 1F60H |
| 21F60H | 2100H | 0F60H |
| 21F60H | 21F0H | 0060H |
| 21F60H | 21F6H | 0000H |
| 21F60H | 1F00H | 2F60H |
結(jié)論:CPU可以用不同的段地址(SA)和偏移地址(EA)形成同一個(gè)物理地址。
(2)如果給定一個(gè)段地址,僅通過(guò)變化偏移地址來(lái)尋址最多可定位多少個(gè)內(nèi)存單元?
結(jié)論:如果給定一個(gè)段地址,僅通過(guò)變化偏移地址來(lái)尋址最多可定位64KB個(gè)內(nèi)存單元。
數(shù)據(jù)在 21F60H 內(nèi)存單元中,CPU 表示 形式為 2000:1F60 單元中。
檢測(cè)點(diǎn) 2.2
(1)給定段地址為0001H,僅通過(guò)變化偏移地址尋址,CPU的尋址范圍為 0001:0000 到 0001:FFFF 。
(2)有一數(shù)據(jù)存放在內(nèi)存 20000H 單元中,現(xiàn)給定段地址為SA,若想用偏移地址尋到此單元。則SA應(yīng)滿(mǎn)足的條件是:最小為 1001H ,最大為 2000H 。
2.9 段寄存器(提供段地址)
8086CPU有4個(gè)段寄存器:CS、DS、SS、ES。
2.10 CS和IP
CS為段寄存器,IP為指令指針寄存器。
一個(gè)例子(展示CPU執(zhí)行指令原理,比較長(zhǎng))
從下面一系列的圖展示過(guò)程。
下面,首先初始化
將CS、IP的內(nèi)容送入地址加法器
地址加法器將物理地址送入輸入輸出控制電路
輸入輸出控制電路將物理地址送到地址總線
內(nèi)存中存放的機(jī)器指令被送入CPU
輸入輸出控制電路將指令送入指令緩沖器
IP中的值自動(dòng)增加,以使CPU可以讀取下一條指令
執(zhí)行控制器執(zhí)行指令
指令被執(zhí)行后,AX內(nèi)容發(fā)生了變化
同上過(guò)程,讀取下一條指令
再讀取下一條!
又讀取一條!
到此為止,4條指令執(zhí)行歷程結(jié)束!
通過(guò)上面的例子,8086CPU的工作過(guò)程可以簡(jiǎn)要描述如下。
8086CPU加電啟動(dòng)或復(fù)位后,CS和IP被設(shè)置為CS=FFFFH,IP=0000H(重要,也就是說(shuō)FFFF0H是8086PC機(jī)開(kāi)機(jī)后執(zhí)行的第一條指令)。
2.11 修改CS、IP的指令
CPU從何處執(zhí)行指令?
顯然,由CS、IP中的內(nèi)容決定的。
我們?nèi)绾胃淖僀S、IP的值呢?
8086CPU提供相應(yīng)的指令。
我們?cè)诔醪搅私鈪R編指令的時(shí)候使用過(guò) mov 指令,那我們能夠使用mov指令來(lái)修改CS、IP的內(nèi)容嗎?
答案是不可以的,因?yàn)?086CPU的mov指令沒(méi)有提供這樣的功能。
我們將用最簡(jiǎn)單的可以修改CS、IP的指令: jmp 指令。
使用方式形如: jmp 段地址 : 偏移地址。這個(gè)指令的功能是修改CS和IP的值。
還有另一種修改方式: jmp 某一合法寄存器。這個(gè)指令的功能是修改IP的值。
問(wèn)題 2.3
指令執(zhí)行序列如下:
2.12 代碼段
對(duì)于8086PC機(jī),在編程時(shí),可以將一組內(nèi)存單元定義為一個(gè)段。我們可以將長(zhǎng)度為 N(N<=64KB) 的一組代碼,存在一組地址連續(xù)、起始地址為16的倍數(shù)的內(nèi)存單元中。我們可以認(rèn)為,這段內(nèi)存是用來(lái)存放代碼的,從而定義了代碼段。
例如:
MOV AX,0000H ;(B8 00 00) ADD AX,0123H ;(05 23 01) MOV BX,AX ;(8B D8) JMP BX ;(FF E3)這段長(zhǎng)度為10個(gè)字節(jié)的指令,存放在123B0H~123B9H的一組內(nèi)存單元中,我們就可以認(rèn)為,123B0H~123B9H這段內(nèi)存時(shí)用來(lái)存放代碼的,是一個(gè)代碼段,它的段地址為123BH,長(zhǎng)度為10個(gè)字節(jié)。
這段代碼如何被執(zhí)行呢?
顯然,只要將CS = 123BH,IP = 0000H即可。
2.9~2.12 小結(jié)
檢測(cè)點(diǎn) 2.3
下面的3條指令執(zhí)行后,CPU幾次修改IP?都是在什么時(shí)候?最后IP中的值是多少?
答案:一次修改 IP,在 JMP AX 的時(shí)候,最后 IP 為0000H。
實(shí)驗(yàn)1 查看CPU和內(nèi)存,用機(jī)器指令和匯編指令編程
1.預(yù)備知識(shí):Debug的使用
(1)什么是Debug?
Debug是 DOS、Windows 都提供的實(shí)模式(8086 方式)程序的調(diào)試工具。使用它,可以查看CPU各種寄存器中的內(nèi)容、內(nèi)存的情況和在機(jī)器碼級(jí)跟蹤程序的運(yùn)行。
(2)我們用到的Debug功能。
- 用Debug的R命令查看、改變CPU寄存器的內(nèi)容;
- 用Debug的D命令查看內(nèi)存中的內(nèi)容;
- 用Debug的E命令改寫(xiě)內(nèi)存中的內(nèi)容;
- 用Debug的U命令將內(nèi)存中的機(jī)器指令翻譯成匯編指令;
- 用Debug的T命令執(zhí)行一條機(jī)器指令;
- 用Debug的A命令以匯編指令的格式在內(nèi)存中寫(xiě)入一條機(jī)器指令。
Debug的命令比較多,共有20多個(gè),但這6個(gè)命令是和匯編學(xué)習(xí)密切相關(guān)的。在以后還有用到一個(gè)P命令。
(3)進(jìn)入Debug。
Debug是在DOS方式下使用的程序。我們?cè)谶M(jìn)入Debug前,應(yīng)先進(jìn)入到DOS方式。
用以下方式可以進(jìn)入DOS。
在這里,我用的是 實(shí)驗(yàn)樓 的環(huán)境。這樣降低了學(xué)習(xí)成本。
(4)用 R命令 查看、改變CPU寄存器的內(nèi)容。
如下,成功顯示了寄存器的內(nèi)容
如下,成功修改了AX寄存器的內(nèi)容
我們注意到 DS:0000 = 0 以后的章節(jié)會(huì)介紹。還看到了最下面一行出現(xiàn)的 TEST …的匯編指令。
可以用 R命令 修改CS和IP的內(nèi)容。
(5)用Debug的 D命令 查看內(nèi)存中的內(nèi)容。
用Debug的D命令,可以查看內(nèi)存中的內(nèi)容,D命令的格式比較多。
可以用:D 段地址 : 偏移地址,如下。
使用D命令,Debug將輸出3部分內(nèi)容,如下。
- 中間是從指定地址開(kāi)始的128個(gè)內(nèi)存單元的內(nèi)容,用十六進(jìn)制的格式輸出。每行的輸出從16的整數(shù)倍的地址開(kāi)始,最多輸出16個(gè)單元的內(nèi)容。
- 左邊是每行的起始地址。
- 右邊是每個(gè)內(nèi)存單元中的數(shù)據(jù)對(duì)應(yīng)的可顯示的 ASCII 碼字符。
(6)用 Debug 的 E命令 改寫(xiě)內(nèi)存中的內(nèi)容。
E 10 ;修改當(dāng)前數(shù)據(jù)段10H號(hào)單元內(nèi)容 E ES:100 ;修改附加段100H號(hào)單元內(nèi)容 D ES:100 ;查看一下100H單元的內(nèi)容是否修改了(7)用E命令向內(nèi)存中寫(xiě)入機(jī)器碼,用U命令查看內(nèi)存中機(jī)器碼的含義,用T命令執(zhí)行內(nèi)容從中的機(jī)器碼。
E命令其他用法
編寫(xiě)一個(gè)如下代碼的匯編程序
MOV AX,0001 ;B80100 MOV CX,0002 ;B90200 ADD AX,CX ;01C8編寫(xiě)代碼如下:
修改CS、IP寄存器
使用T命令執(zhí)行匯編指令
觀察以上所有圖片寄存器的變化(眼睛都花了)。
(8)用Debug的 A命令 以匯編指令形式在內(nèi)存中寫(xiě)入機(jī)器指令。
如圖。
從最后一行可以看出,內(nèi)存1000H段的內(nèi)容已經(jīng)被修改成功。
最后,在一張命令表格吧。
| R命令 | 查看、修改CPU |
| D命令 | 查看內(nèi)存中的內(nèi)容 |
| E命令 | 修改內(nèi)存中的內(nèi)容 |
| U命令 | 將內(nèi)存中的內(nèi)容解釋為機(jī)器指令和對(duì)應(yīng)的匯編指令 |
| T命令 | 執(zhí)行CS:IP指向的內(nèi)存單元處的指令 |
| A命令 | 以匯編指令的形式向內(nèi)存中寫(xiě)入指令 |
2. 實(shí)驗(yàn)任務(wù)
(1)使用 Debug,將下面的程序段寫(xiě)入內(nèi)存,逐條執(zhí)行,觀察每條指令執(zhí)行后,CPU中相關(guān)寄存器中內(nèi)容的變化。
匯編指令 機(jī)器碼 MOV AX,4E20H ;B8 20 4E ADD AX,1416H ;05 16 14 MOV BX,2000H ;BB 00 20 ADD AX,BX ;01 D8 MOV BX,AX ;89 C3 ADD AX,BX ;01 D8 MOV AX,001AH ;B8 1A 00 MOV BX,0026H ;BB 26 00 ADD AL,BL ;00 D8 ADD AH,BL ;00 DC ADD BH,AL ;00 C7 MOV AH,0 ;B4 00 ADD AL,BL ;00 D8 ADD AL,9CH ;04 9CDebug下用A命令輸入?yún)R編指令:
再用D命令查看是否輸入?yún)R編指令到內(nèi)存:
在使用R命令查看和修改CS、IP的值,修改成代碼段的開(kāi)始位置:
最后,T命令執(zhí)行,自行實(shí)驗(yàn)觀察步驟。
整個(gè)過(guò)程只要觀察AX和BX就好,最后AX=0002,BX=4026。
(2)將下面3條指令寫(xiě)入從 2000:0 開(kāi)始的內(nèi)存單元中,利用這3條指令計(jì)算2的8次方。
mov ax,1 add ax,ax jmp 2000:0003分析,我們知道 mov ax,1 占了3個(gè)內(nèi)存單元。所以我們代碼段的開(kāi)始位置為2000H。
如下(要算2的8次方,add ax,ax,這個(gè)跟算法的快速冪一樣,我們只要add ax,ax四次就行,因?yàn)閍x初始化為1):
(3)查看內(nèi)存中的內(nèi)容。
PC機(jī)主板上的ROM中寫(xiě)有一個(gè)生產(chǎn)日期,在內(nèi)存 FFF00H~FFFFFH 的某幾個(gè)單元中,請(qǐng)找到這個(gè)生產(chǎn)日期,在內(nèi) FFF00H~FFFFFH 的某幾個(gè)單元中,請(qǐng)找出這個(gè)生產(chǎn)日期并試圖改變它。
顯然,用D FFF0 : 0000 L 100就可以得出答案,如下。
(4)向內(nèi)存從B8100H開(kāi)始的單元中填寫(xiě)數(shù)據(jù),如:
-e B8100:0000 01 01 02 02 03 03 04 04發(fā)現(xiàn):數(shù)據(jù)沒(méi)有被改變,為什么呢?
原因:我們閱讀第一章的時(shí)候,我們知道我們將所有內(nèi)存當(dāng)做一個(gè)邏輯連續(xù)的內(nèi)存。而B810H地址段是ROM(只讀)的內(nèi)存段。
真的太多了,碼了一天。
總結(jié)
以上是生活随笔為你收集整理的寄存器---汇编学习笔记的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 做数据产品经理要学习那些东西?
- 下一篇: 产品经理如何避免被程序员打?