【自學組合語言Day-02】第二章:暫存器(CPU工作原理)
文章目錄
參考書籍:《組合語言(第2版)》——王爽,參考視訊:《零基礎入門學習組合語言》——小甲魚
第二章:暫存器(CPU工作原理)
前言
一個典型的CPU由運算器、控制器、暫存器等器件組成,這些器件靠內部匯流排相連。
內部匯流排實現CPU內部各個器件之間的聯絡。
外部匯流排實現CPU和主機板上其它器件的聯絡。
不同的CPU,暫存器的個數和結構是不相同的。
8086CPU有14個暫存器,它們的名稱分別為:AX、BX、CX、DX、SI、DI、SP、BP、IP、CS、SS、DS、ES、PSW。
2.1 通用暫存器
8086CPU的所有暫存器都是16位的,可以存放兩個位元組。
AX、BX、CX、DX這4個暫存器通常用來存放一般性的資料,被稱為通用暫存器。
資料:20000
二進位制表示:0100111000100000
在暫存器AX中的儲存:
一個16位暫存器能儲存的資料最大值為2^16-1。
8086上一代CPU中的暫存器都是8位的,為保證相容性,8086CPU中的AX、BX、CX、DX這4個暫存器都可以分為兩個獨立的8位暫存器使用,H為高8位,L為低8位。
- AX可分為AH和AL;
- BX可分為BH和BL;
- CX可分為CH和CL;
- DX可分為DH和DL;
以AX為例,8086CPU的16位暫存器分為兩個8位暫存器的情況如下圖所示。
2.2 字在暫存器中的儲存
字:記為word,一個字由兩個位元組組成,這兩個位元組分別成為高位位元組和低位位元組。
關於數制的討論
由於一個記憶體單元可以存放8位資料,CPU中的暫存器又可存放n個8位資料。也就是說,計算機中的資料大多是由1~n個8位資料構成的。
用16進位制來表示資料可以直觀的看出這個資料是由哪些8位資料構成的,每4個二進位制位能夠表示一個16進位制數。
2.3 幾條彙編指令
彙編指令或暫存器的名稱不區分大小寫。
課本例題
add al,93H ,在執行前,al中的資料為C5H,相加後所得的值為158H,但是al為8位暫存器,只能存放兩位16進位制數,所以最高位的1丟失,ax的資料為:0058H。
這裡的丟失,指的是進位值不能在8位暫存器中儲存,但是CPU並不是真的丟棄這個進位值,關於這個問題,我們將在後面的課程中討論。
注意,此時al作為一個獨立的8位暫存器來使用,和ah沒有關係。CPU在執行這條指令時認為ah和al是兩個不相關的暫存器。不要錯誤地認為,諸如add al,93H 的指令產生的進位會儲存在ah中。
在進行資料傳送或運算時,要注意指令的兩個操作物件的位數應當是一致的。
例如,以下指令都是錯誤的:
mov ax,bl (在8位暫存器和16位暫存器之間傳送資料)
mov ah,ax (在16位暫存器和8位暫存器之間傳送資料)
mov al,20000 (8位暫存器最大可存放值為255的資料)
add al,100H (將一個高於8位的資料加到一個8位暫存器中)
檢測點2.1
(1)寫出每條彙編指令執行後相關暫存器中的值。
mov ax,62627 AX=F4A3H
mov ah,31H AX=31A3H
mov al,23H AX=3123H
add ax,ax AX=6246H
mov bx,826CH BX=826CH
mov cx,ax CX=6246H
mov ax,bx AX=826CH
add ax,bx AX=04D8H
mov al,bh AX=0482H
mov ah,bl AX=6C82H
add ah,ah AX=D882H
add al,6 AX=D888H
add al,al AX=D810H
mov ax,cx AX=6246H
解析: 將暫存器看成4個16進位制數相加減,注意進位的丟失問題即可。
舉例:第8空:add ax,bx AX = 826CH + 826CH = 104D8H,最高位1會丟失,所以最後答案為04D8H。
(2)只能使用目前學過的彙編指令,最多使用4條指令,程式設計計算2的4次方。
mov ax,2 AX=2
add ax,ax AX=4
add ax,ax AX=8
add ax,ax AX=16
2.4 實體地址
CPU訪問記憶體單元時,要給出記憶體單元的地址。所有的記憶體單元構成的儲存空間是一個一維的線性空間,每一個記憶體單元在這個空間中都有唯一的地址,我們將這個唯一的地址稱為實體地址。
2.5 16位結構的CPU
16位結構描述了一個CPU具有以下3個方面的結構特性:
- 運算器一次最多可以處理16位的資料;
- 暫存器的最大寬度為16位;
- 暫存器和運算器之間的通路為16位。
記憶體單元的地址在送上地址匯流排之前,必須在CPU中處理、傳輸、暫時存放,8086是16位結構的CPU,能夠一次性處理、傳輸、暫時儲存16位的地址。
2.6 8086CPU給出實體地址的方法
8086有20位地址匯流排,可以傳送20位地址,定址能力為1MB。
而8086CPU的內部又是16位結構,如果將地址從內部簡單地發出,那麼它只能送出16位的地址,表現出的定址能力只有64KB。
8086CPU採用一種在內部用兩個16位地址合成的方法來形成一個20位的實體地址。
如圖所示,當8086CPU要讀寫記憶體時:
(1)CPU中相關部件提供兩個16位的地址,一個稱為段地址,另一個稱為偏移地址;
(2)段地址和偏移地址通過內部匯流排送入一個稱為地址加法器的部件;
(3)地址加法器將兩個16位地址合成為一個20位的實體地址;
(4)地址加法器通過內部匯流排將20位實體地址送入輸入輸出控制電路;
(5)輸入輸出控制電路將20位實體地址送上地址匯流排;
(6)20位實體地址被地址匯流排傳送到儲存器(記憶體)。
地址加法器計算實體地址的方法:
實體地址=段地址×16+偏移地址
例如:8086CPU要訪問地址為123C8H的記憶體單元,此時,地址加法器的工作過程如下圖所示(圖中資料皆為16進位制)。
"段地址×16"更為常用的說法是左移4位(2進位制位)。
將16進位制數2H進行左移運算:
(1)一個資料的二進位制形式左移1位,相當於該資料乘以2;
(2)一個資料的二進位制形式左移N位,相當於該資料乘以2的N次方;
(3)地址加法器如何完成段地址×16的運算?就是將以二進位制形式存放的段地址左移4位。
綜上,一個X進位制的資料左移1位,相當於該資料乘以X。
2.7 “段地址×16+偏移地址=實體地址”的本質含義”
“段地址×16+偏移地址=實體地址”的本質含義是:CPU在訪問記憶體時,用一個基礎地址(段地址×16)和一個相對於基礎地址的偏移地址相加,給出記憶體單元的實體地址。
2.8 段的概念
錯誤認識:
記憶體被劃分成了一個一個的段,每一個段有一個段地址。
其實:
記憶體並沒有分段,段的劃分來自於CPU,由於8086CPU用“基礎地址(段地址×16)+偏移地址=實體地址”的方式給出記憶體單元的實體地址,使得我們可以用分段的方式來管理記憶體。
以後,在程式設計時可以根據需要,將若干地址連續的記憶體看作一個段,用段地址×16定位段的起始地址(基礎地址),用偏移地址定位段中的記憶體單元。即起始地址+偏移地址=實體地址的思想。
兩個注意點:
(1)段地址×16必然是16的倍數,所以一個段的起始地址也一定是16的倍數;
(2)偏移地址為16位,16位地址的定址能力為64KB,所以一個段的長度最大為64KB。
記憶體單元地址小結
-
CPU訪問記憶體單元時,必須向記憶體提供記憶體單元的實體地址。
-
8086CPU在內部用段地址和偏移地址移位相加的方法形成最終的實體地址。
-
CPU可以用不同的段地址和偏移地址形成同一個實體地址。
-
偏移地址為16位,變化範圍為0~FFFFH,僅用偏移地址來定址最多可尋64K個記憶體單元。
-
“資料在21F60H記憶體單元中。”對於8086PC機的兩種描述:
(a)資料存放在記憶體2000:1F60單元中;(較常用)
(b)資料存放在記憶體的2000段中的1F60H單元中。 -
可根據需要,將地址連續、起始地址為16的倍數的一組記憶體單元定義為一個段。
檢測點2.2
(1)給定段地址為0001H,僅通過變化偏移地址定址,CPU的定址範圍為00010H到1000FH。
解析:
實體地址=SA * 16 + EA
EA的變化範圍為0H ~ FFFFH
實體地址範圍為(SA * 16 + 0H)~ (SA * 16 + FFFFH)
現在SA=0001H,那麼定址範圍為(0001H * 16 + 0H)~(0001H * 16 + FFFFH) = 00010H ~ 1000FH
(2)有一資料存放在記憶體20000H單元中,現給定段地址為SA,若想用偏移地址尋到此單元。則SA應滿足的條件是:最小是1001H,2000H。
解析:
實體地址=SA * 16 + EA
20000h=SA * 16 + EA
SA = (20000H - EA) / 16 = 2000H - EA / 16
EA取最大值時,SA = 2000H - FFFFH / 16 = 1001H,SA為最小值
EA取最小值時,SA = 2000H - 0H / 16 = 2000H,SA為最大值
這裡的FFFFH / 16 = FFFH是通過WIN自帶計算器算的,按位移來算確實應該為FFF.FH,這裡小數點後的F應該是省略了,單就除法來說,應有商和餘數,但此題要求的是地址最大和最小,所以餘數忽略了。
如果根據位移的演算法(段地址×16=16進位制左移一位),小數點後應該是不能省略的,我們可以反過來再思考下,如果SA為1000H的話,小數點後省略SA=1000H,EA取最大FFFFH,實體地址為1FFFFH,將無法尋到20000H單元 這道題不應看成是單純的計算題。
2.9 段暫存器
8086CPU有4個段暫存器:CS、DS、SS、ES。當8086CPU要訪問記憶體時由這4個段暫存器提供記憶體單元的段地址。
2.10 CS和IP
CS和IP是8086中最關鍵的兩個暫存器,它們指示了CPU當前要讀取指令的地址。CS為程式碼段暫存器,IP為指令指標暫存器。
任意時刻,設CS中的內容為M,IP中的內容為N,8086CPU將從記憶體M×16+N單元開始,讀取一條指令並執行。
8086CPU的工作過程可以簡要描述如下。
(1)從CS:IP指向的記憶體單元讀取指令,讀取的指令進入指令緩衝器;
(2)IP=IP+所讀取指令的長度,從而指向下一條指令;
(3)執行指令。轉到步驟(1),重複這個過程。
在8086CPU加電啟動或復位後(即CPU剛開始工作時),CS和IP被設定為CS=FFFFH,IP=0000H。
即在8086PC機剛啟動時,CPU從記憶體FFFF0H單元中讀取指令執行,該單元中的指令是8086PC機開機後執行的第一條指令。
在任何時候,CPU將CS、IP中的內容當作指令的段地址和偏移地址,用它們合成指令的實體地址到記憶體中讀取指令碼並執行。
如果說,記憶體中的一段資訊曾被CPU執行過的話,那麼,它所在的記憶體單元必然被CS:IP指向過。
2.11 修改CS、IP的指令
在CPU中,程式設計師能夠用指令讀寫的部件只有暫存器,程式設計師可以通過改變暫存器中的內容實現對CPU的控制。
CPU從何處執行指令是由CS、IP中的內容決定的,程式設計師可以通過改變CS、IP中的內容來控制CPU執行目標指令。
-
同時修改CS、IP的內容:
jmp 段地址:偏移地址
jmp 2AE3:3
jmp 3:0B16
注意:jmp 3:0B16
是指CS=0003H,IP=0B16。 -
僅修改IP的內容:
jmp 某一合法暫存器
jmp ax (類似於mov IP,ax)
jmp bx
例題:
初始:CS=2000H,IP=0000H
執行步驟為:
(1)mov ax,6622
(2)jmp 1000:3
(3)mov ax,0000
(4)mov bx,ax
(5)jmp bx
(6)mov ax,0123H
(7)轉到第(3)步執行(不斷迴圈)
2.12 程式碼段
對於8086PC機,在程式設計時,可以根據需要,將一組記憶體單元定義為一個段。
可以將長度為N(N≤64KB)的一組程式碼,存在一組地址連續、起始地址為16的倍數的記憶體單元中,這段記憶體是用來存放程式碼的,從而定義了一個程式碼段。
例如:
這段長度為10位元組的指令,存在從123B0H ~ 123B9H的一組記憶體單元中,我們就可以認為,123B0H ~ 123B9H這段記憶體單元是用來存放程式碼的,是一個程式碼段,它的段地址為123BH,長度為10位元組。
- 如何使得程式碼段中的指令被執行呢?
將一段記憶體當作程式碼段,僅僅是我們在程式設計時的一種安排,CPU並不會由於這種安排,就自動地將我們定義的程式碼段中的指令當作指令來執行。
CPU只認被CS:IP指向的記憶體單元中的內容為指令。
2.9 ~ 2.12 小結
-
段地址在8086CPU的暫存器中存放。當8086CPU要訪問記憶體時,由段暫存器提供記憶體單元的段地址。8086CPU有4個段暫存器,其中CS用來存放指令的段地址。
-
CS存放指令的段地址,IP存放指令的偏移地址。
8086機中,任意時刻,CPU將CS:IP指向的內容當作指令執行。 -
8086CPU的工作過程:
(1)從CS:IP指向記憶體單元讀取指令,讀取的指令進入指令緩衝器;
(2)IP指向下一條指令;
(3)執行指令。(轉到步驟(1),重複這個過程。) -
8086CPU提供轉移指令修改CS、IP的內容。(jmp)
檢測點2.3
下面的3條指令執行後,CPU幾次修改IP?都是在什麼時候?最後IP中的值是多少?(sub 為減)
mov ax,bx
sub ax,bx
jmp ax
答:一共修改四次。
第一次:讀取mov ax,bx之後
第二次:讀取sub ax,ax之後
第三次:讀取jmp ax之後
第四次:執行jmp ax修改IP
最後IP的值為0000H,因為最後ax中的值為0000H,所以IP中的值也為0000H。
實驗1 檢視CPU和記憶體,用機器指令和彙編指令程式設計
1. 預備知識:Debug的使用
Debug是DOS、Windows都提供的真實模式(8086方式)程式的除錯工具。使用它,可以檢視CPU各種暫存器中的內容、記憶體的情況和在機器碼級跟蹤程式的執行。
win10下Debug的安裝與配置:https://www.cnblogs.com/zhaijiahui/p/10148698.html
或者在虛擬機器裝個XP系統開啟cmd就可以直接用了。
Debug基本命令:
- R命令:檢視、改變CPU暫存器的內容;
- D命令:檢視記憶體中的內容;
- E命令:改寫記憶體中的內容;
- U命令:將記憶體中的機器指令翻譯成彙編指令;
- T命令:執行一條機器指令;
- A命令:以彙編指令的格式在記憶體中寫入一條機器指令。
2. 示例:
- 用R命令檢視、改變CPU暫存器的內容。
我們已經知道AX、BX、CX、DX、CS、IP這6個暫存器,其他暫存器如SP、BP、SI、DI、DS、ES、SS、標誌暫存器等先不予理會。
此時,CS=073F,IP=0100,也就是說記憶體073F:0100處的指令為CPU當前要讀取、執行的指令。
在所有的暫存器下方,Debug還列出了CS:IP所指向的記憶體單元073F:0100所存放的機器碼0000,並將它翻譯成彙編指令ADD [BX+SI],AL。
還可以用R命令來改變暫存器中的內容,如輸入“r ax”後按Enter鍵,將出現“:”,然後我們輸入1111,這樣就把AX中的內容改成了1111,然後我們再用R命令檢視一下。
- 用D命令檢視記憶體中的內容。
格式:“d 段地址:偏移地址”
如檢視FFFF0H處的內容,Debug將自動列出從指定記憶體單元開始的128個記憶體單元的內容,如下圖。從FFFF:0 ~ FFFF:F的內容在第一行,中間的橫線是分隔符,左邊是0 ~ 7,右邊是8 ~ F,這樣便於檢視。中間是每個記憶體單元的內容,用16進位制數表示。右邊是每個記憶體單元中的資料對應的可顯示的ASCⅡ碼字元。
- 用E命令改寫記憶體中的內容。
比如將記憶體1000:0 ~ 1000:9單元中的記憶體分別改成0、1、2、3、4、5、6、7、8、9,可以用“e 起始地址 資料 資料 資料 資料……”的格式來進行。
然後用d命令檢視1000:0 ~ 1000:F中的內容。
- 用E命令向記憶體中寫入機器碼,用U命令檢視記憶體中機器碼的含義,用T命令執行記憶體中的機器碼。
(1)用E命令將機器碼b80100(mov ax,0001),b90200(mov cx,0002),01c8(add ax,cx)寫入記憶體1000:0中。然後用“u 1000:0”將從1000:0開始的記憶體單元中的內容翻譯為彙編指令。
可以看到前三條指令就是我們剛才寫入的。然後如何執行呢?要想用T命令控制CPU執行我們寫在1000:0的指令,必須先讓CS:IP指向1000:0。所以我們先用R命令檢視並修改CS、IP中的內容。
如上圖,修改完成後,就可以用T命令來執行我們寫入的指令了。如下圖,根據我們之前寫入的指令觀察相關暫存器內容的變化。
- 用A命令以彙編指令的形式在記憶體中寫入機器指令。
前面我們使用E命令寫入機器指令,這樣很不方便,我們可以用A命令直接寫入彙編指令。如下圖,我們先用A命令寫入幾條彙編指令,結束時按Enter即可,然後用D命令檢視記憶體中的機器碼,然後用U命令將記憶體中的機器碼翻譯成彙編指令,可以看出和我們輸入的彙編指令是一樣的。
相關文章
- 組合語言學習筆記03——暫存器(CPU工作原理)組合語言筆記
- x86 組合語言標誌暫存器組合語言
- 組合語言中暫存器的英文全程組合語言
- 【組合語言】第 3 章 暫存器(記憶體訪問)組合語言記憶體
- 《組合語言》王爽,學習筆記(標誌暫存器下)組合語言筆記
- 第二章--組合語言組合語言
- 自學C day03-CPU內部結構和暫存器
- 讀書筆記《組合語言》——intel8086暫存器的記憶體訪問筆記組合語言Intel記憶體
- 組合語言1 - 什麼是組合語言?組合語言
- 組合語言組合語言
- 組合語言 1組合語言
- 組合語言 2組合語言
- 組合語言-棧組合語言
- Smali語法:Registers(暫存器)
- 這個處理器的組合語言:組合語言
- CPU中跟蹤後繼指令地址的暫存器
- 組合語言指令大全組合語言
- CS 暫存器 和 IP 暫存器
- 機器碼 指令 組合語言 的關係機器碼組合語言
- 暫存器
- 組合語言-基礎功能組合語言
- 組合語言——更多功能組合語言
- 組合語言---判斷字元組合語言字元
- 組合語言入門教程組合語言
- Go 語言的組合之道Go
- 組合語言-基礎知識組合語言
- 8086執行組合語言組合語言
- 組合語言--單步中斷組合語言
- 組合語言學習筆記組合語言筆記
- 組合語言的藝術(轉)組合語言
- ARM組合語言最常用指令組合語言
- 組合語言-CALL和RET指令組合語言
- Intel組合語言程式設計學習-第二章 IA-32處理器體系結構-上Intel組合語言程式設計
- 8.ARM工作模式和暫存器及異常模式
- Git工作區和暫存區Git
- 暫存器定址和暫存器間接定址的區別
- 組合語言-學習記錄(二)組合語言
- 基於MDK建立純組合語言--組合語言