1. 程式人生 > >匯編語言--CPU資源和存儲器(二)

匯編語言--CPU資源和存儲器(二)

direct 公式 專用 例子 1-1 star display 獲得 而且

二、CPU資源和存儲器

需要訪問的硬件資源主要有:CPU內部資源、存儲器和I/O端口。

1、寄存器組

(1)16位寄存器組

16位CPU所含有的寄存器有(見圖2.1中16位寄存器部分):

4個數據寄存器(AX、BX、CX和DX)

2個變址和指針寄存器(SI和DI)

2個指針寄存器(SP和BP)

4個段寄存器(ES、CS、SS和DS)

1個指令指針寄存器(IP)

1個標誌寄存器(Flags)

(2)32位寄存器組

32位CPU除了包含了先前CPU的所有寄存器,並把通用寄存器、指令指針和標誌寄存器從16位擴充成32位之外,還增加了2個16位的段寄存器:FS和GS。

32位CPU所含有的寄存器有(見圖2.1中的寄存器):

4個數據寄存器(EAX、EBX、ECX和EDX)

2個變址和指針寄存器(ESI和EDI)

2個指針寄存器(ESP和EBP)

6個段寄存器(ES、CS、SS、DS、FS和GS)

1個指令指針寄存器(EIP)

1個標誌寄存器(EFlags)

技術分享圖片

(3)通用寄存器的作用

表2.1 通用寄存器的主要用途

技術分享圖片

(4)專用寄存器的作用

16位CPU內部有一個16位的標誌寄存器,它包含9個標誌位。這些標誌位主要用來反映處理器的狀態和運算結果的某些特征。各標誌位在標誌寄存器內的分布如圖2.2所示。

技術分享圖片

上面9個標誌位可分為二組:運算結果標誌位(有背景色的標誌位)和狀態控制標誌位。前者受算術運算和邏輯運算結果的影響,後者受一些控制指令執行的影響。

16位標誌寄存器——共用了9個標誌位,標誌位的分布如下表所示。

技術分享圖片

32位標誌寄存器——32位CPU也把標誌寄存器擴展到32位,記為EFLAGS。它新增加了四個控制標誌位,它們是:IOPL、NT、RF和VM,這些標誌位在實方式下不起作用。其它標誌位的位置和作用與先前的完全相同。

其主要標誌位的分布如下表所示:

技術分享圖片

有些指令的執行會改變標誌位(如:算術運算指令等),不同的指令會影響不同的標誌位,有些指令的執行不改變任何標誌位(如:MOV指令等),有些指令的執行會受標誌位的影響(如:條件轉移指令等),也有指令的執行不受其影響。

程序員要想熟練運用這些標誌位,就必須掌握每個標誌位的含義、每條指令的執行條件和執行結果對標誌位的作用。

註意:雖然知道每個標誌位在標誌寄存器內的具體位置是有好處的,但通常情況下,沒有這個必要。在使用後面的“條件轉移指令”時,系統會自動引用相應標誌位的值來決定是否需要“轉移”的,所以,不必過分強調標誌位在標誌寄存器內的具體位置。

----------------------------------------------------------------------------------------------------------------------

知識點補充:

一、運算結果標誌位

1、進位標誌CF(Carry Flag)

進位標誌CF主要用來反映運算是否產生進位或借位。如果運算結果的最高位產生了一個進位或借位,那麽,其值為1,否則其值為0。

使用該標誌位的情況有:多字(字節)數的加減運算,無符號數的大小比較運算,移位操作,字(字節)之間移位,專門改變CF值的指令等。

2、奇偶標誌PF(Parity Flag)

奇偶標誌PF用於反映運算結果中“1”的個數的奇偶性。如果“1”的個數為偶數,則PF的值為1,否則其值為0。

利用PF可進行奇偶校驗檢查,或產生奇偶校驗位。在數據傳送過程中,為了提供傳送的可靠性,如果采用奇偶校驗的方法,就可使用該標誌位。

3、輔助進位標誌AF(Auxiliary Carry Flag)

在發生下列情況時,輔助進位標誌AF的值被置為1,否則其值為0:

(1)、在字操作時,發生低字節向高字節進位或借位時;
(2)、在字節操作時,發生低4位向高4位進位或借位時。

對以上6個運算結果標誌位,在一般編程情況下,標誌位CF、ZF、SF和OF的使用頻率較高,而標誌位PF和AF的使用頻率較低。

4、零標誌ZF(Zero Flag)

零標誌ZF用來反映運算結果是否為0。如果運算結果為0,則其值為1,否則其值為0。在判斷運算結果是否為0時,可使用此標誌位。

5、符號標誌SF(Sign Flag)

符號標誌SF用來反映運算結果的符號位,它與運算結果的最高位相同。在微機系統中,有符號數采用補碼表示法,所以,SF也就反映運算結果的正負號。運算結果為正數時,SF的值為0,否則其值為1。

6、溢出標誌OF(Overflow Flag)

溢出標誌OF用於反映有符號數加減運算所得結果是否溢出。如果運算結果超過當前運算位數所能表示的範圍,則稱為溢出,OF的值被置為1,否則,OF的值被清為0。

二、狀態控制標誌位

狀態控制標誌位是用來控制CPU操作的,它們要通過專門的指令才能使之發生改變。

1、追蹤標誌TF(Trap Flag)

當追蹤標誌TF被置為1時,CPU進入單步執行方式,即每執行一條指令,產生一個單步中斷請求。這種方式主要用於程序的調試。

指令系統中沒有專門的指令來改變標誌位TF的值,但程序員可用其它辦法來改變其值。

2、中斷允許標誌IF(Interrupt-enable Flag)

中斷允許標誌IF是用來決定CPU是否響應CPU外部的可屏蔽中斷發出的中斷請求。但不管該標誌為何值,CPU都必須響應CPU外部的不可屏蔽中斷所發出的中斷請求,以及CPU內部產生的中斷請求。具體規定如下:

(1)、當IF=1時,CPU可以響應CPU外部的可屏蔽中斷發出的中斷請求;

(2)、當IF=0時,CPU不響應CPU外部的可屏蔽中斷發出的中斷請求。

CPU的指令系統中也有專門的指令來改變標誌位IF的值。

3、方向標誌DF(Direction Flag)

方向標誌DF用來決定在串操作指令執行時有關指針寄存器發生調整的方向。具體規定在第5.2.11節——字符串操作指令——中給出。在微機的指令系統中,還提供了專門的指令來改變標誌位DF的值。

、32位標誌寄存器增加的標誌位

1、I/O特權標誌IOPL(I/O Privilege Level)

I/O特權標誌用兩位二進制位來表示,也稱為I/O特權級字段。該字段指定了要求執行I/O指令的特權級。如果當前的特權級別在數值上小於等於IOPL的值,那麽,該I/O指令可執行,否則將發生一個保護異常。

2、嵌套任務標誌NT(Nested Task)

嵌套任務標誌NT用來控制中斷返回指令IRET的執行。具體規定如下:

(1)、當NT=0,用堆棧中保存的值恢復EFLAGS、CS和EIP,執行常規的中斷返回操作;

(2)、當NT=1,通過任務轉換實現中斷返回。

3、重啟動標誌RF(Restart Flag)

重啟動標誌RF用來控制是否接受調試故障。規定:RF=0時,表示“接受”調試故障,否則拒絕之。在成功執行完一條指令後,處理機把RF置為0,當接受到一個非調試故障時,處理機就把它置為1。

4、虛擬8086方式標誌VM(Virtual 8086 Mode)

如果該標誌的值為1,則表示處理機處於虛擬的8086方式下的工作狀態,否則,處理機處於一般保護方式下的工作狀態。

----------------------------------------------------------------------------------------------------------------------

2、存儲器的管理模式

16位微機的內存管理模式

(1)存儲器的分段

我們知道:計算機的內存單元是以“字節”為最小單位進行線性編址的。為了標識每個存儲單元,就給每個存儲單元規定一個編號,此編號就是該存儲單元的物理地址。

存儲單元的物理地址是一個無符號的二進制數。但為了書寫的簡化,物理地址通常用十六進制來表示。

16位CPU內部有20根地址線,其編碼區間為:00000H~0FFFFFH,所以,它可直接訪問的物理空間為1M(220)字節。而16位CPU內部存放存儲單元偏移量的寄存器(如:IP、SP、BP、SI、DI和BX等)都是16位,它們的編碼範圍僅為:00000H~0FFFFH。這樣,如果用16位寄存器來訪問內存的話,則只能訪問內存的最低端的64K,其它的內存將無法訪問。為了能用16位寄存器來有效地訪問1M的存儲空間,16位CPU采用了內存分段的管理模式,並引用段寄存器的概念。

16位微機把內存空間劃分成若幹個邏輯段,每個邏輯段的要求如下:

邏輯段的起始地址(通常簡稱為:段地址)必須是16的倍數,即最低4位二進制必須全為0;

邏輯段的最大容量為64K,這由16位寄存器的尋址空間所決定。

按上述規定,1M內存最多可分成64K個段,即65536個段(段之間相互重疊),至少可分成16個相互不重疊的段。

圖2.4是內存各邏輯段之間的分布情況示意圖,其中有相連的段(如:C和D段)、不相連的段(如:A和B段)以及相互重疊的段(如:B和C段)。

這種存儲器分段的內存管理方法不僅實現了用兩個16位寄存器來訪問1M的內存空間,而且對程序的重定位、浮動地址的編碼和提高內存的利用率等方面都具有重要的實用價值。

技術分享圖片

(2)物理地址的形成方式

由於規定段地址必須是16的倍數,所以,其值的一般形式為:XXXX0H,即:前16位二進制位是變化的,後四位是固定為0。鑒於段地址的這種特性,我們可以僅保存其前16位二進制來達到保存整個段地址,其後四位可通過“左移補0”來獲得。

在確定了某個存儲單元所屬的內存段後,我們也只知道其所處內存位置的範圍,還不能確定其具體位置。要想確定內存單元的具體位置,還必須知道該單元離該段地址有多遠。我們通常把存儲單元的實際地址與其所在段的段地址之間的距離稱為段內偏移,也可稱為有效地址(EA—Effective Address)或偏移量(Offset)等。有了段地址和偏移量,就能唯一地確定某一內存單元在存儲器內的具體位置。

由此可見,存儲單元的邏輯地址分為兩部分:段地址和偏移量。由邏輯地址得到其物理地址(PA—Physical Address)的計算方法如下:

物理地址PA=段地址×16 + 偏移量

計算存儲單元物理地址的公式可用“左移4位”和“加”運算來實現。圖2.5是物理地址的計算示意圖。

技術分享圖片

對物理地址來說,當段地址變化時,只要對其偏移量進行相應的調整就可對應同一個物理地址,所以,同一個物理地址可有多個邏輯地址。如圖2.6所示。

在匯編語言程序中,存儲單元通常不是用其物理地址標識的,而是用其邏輯地址標識的。邏輯地址的段地址由段寄存器給出,偏移量可由寄存器(SI、DI、BP和BX等)給出,也可用符號地址或具體的數值給出。

(3)段寄存器的引用

段寄存器是因為對內存的分段管理而設置的。16位CPU有四個段寄存器,所以,其程序可同時訪問四個不同含義的段。段寄存器及其偏移量的引用關系如圖2.7所示。

技術分享圖片

段寄存器CS指向存放程序的內存段,IP是用來存放下條待執行的指令在該段的偏移量,把它們合在一起可在該內存段內取到下次要執行的指令。

段寄存器SS指向用於堆棧的內存段,SP是用來指向該堆棧的棧頂,把它們合在一起可訪問棧頂單元。另外,當偏移量用到了指針寄存器BP,則其缺省的段寄存器也是SS,並且用BP可訪問整個堆棧,不僅僅是只訪問棧頂。

段寄存器DS指向數據段,ES指向附加段,在存取操作數時,二者之一和一個偏移量合並就可得到存儲單元的物理地址。該偏移量可以是具體數值、符號地址和指針寄存器的值等之一,具體情況將由指令的尋址方式來決定。

通常,缺省的數據段寄存器是DS,只有一個例外,即:在進行串操作時,其目的地址的段寄存器規定為ES。當然,在一般指令中,我們還可以用強置前綴的方法來改變操作數的段寄存器。

一般情況下,段寄存器及其指針寄存器的引用關系如下表所示。表2.2中的“可選用的段寄存器”即是可以用強置說明這些段寄存器的值來作為其操作數地址的段地址。

表2.2 段寄存器及其指針寄存器的引用關系

技術分享圖片

由上表可以看出16位CPU在段寄存器的引用方面有如下規定:

l 取指令所用的段寄存器和偏移量一定是用CS和IP;

l 堆棧操作所用的段寄存器和偏移量一定是SS和SP;

l 串操作的目標操作數所用的段寄存器和偏移量一定是ES和DI;

l 其它情況,段寄存器除了其默認引用的寄存器外,還可以強行改變為其它段寄存器。

(4)存儲單元的內容

上面,我們講述了16位微機的內存管理及其相關知識,知道了內存單元物理地址的計算方法,這使我們能很容易地指定所要訪問的存儲單元。但存儲單元裏的內容是如何存放的呢?下面就能描述數值在內存的存放形式。

存儲單元中所存放的二進制信息通常稱為該存儲單元的內容或值,並且規定:

l 一個字節的內容是該字節單元內存放的二進制信息;

l 一個字的內容是該字地址所指向的單元及其後繼一個單元的內容拼接而成;

l 一個雙字的內容是該字地址所指向的單元及其後繼三個單元的內容拼接而成。

在拼接“字內容”時,我們按“高高低低”的原則來處理,即:高存儲單元(地址大的存儲單元)的值是“字內容”的高8位,低存儲單元(地址小的存儲單元)的值是“字內容”的低8位。在拼接“雙字內容”時也是如此。

圖2.8是一段內存單元存放數據的例子。

從圖中可看出下列存儲結果:

l 字節12340H、12341H的內容分別為:12H和34H等;

l 字12340H、12341H的內容分別為:3412H和5634H等;

l 雙字12340H、12341H的內容分別為:78563412H和90785634H等。

技術分享圖片

32位微機的內存管理模式

32位微機的內存存管理仍然采用“分段”的管理模式,存儲器的邏輯地址同樣由段地址和偏移量兩部分組成。32位微機的內存管理與16位微機的有相同之處,也有不同之處,因為它提供了兩種不同工作方式:實方式和保護方式。

1、物理地址的計算方式

實方式:段地址仍然是16的倍數,每個段的最大容量仍為64K。段寄存器的值是段的起始地址,存儲單元的物理地址仍為段寄存器的值乘16,再加上段內偏移量。在此方式下,32位微機的內存管理與16位微機是相一致的。

保護方式:段地址可以長達32位,其值可以不是16的倍數,每個段的最大容量可達4G。段寄存器的值是表示段地址的“選擇器”(Selector),用該“選擇器”可從內存中得到一個32位的段地址,存儲單元的物理地址就是該段地址加上段內偏移量,這與16位微機的物理地址計算完全不同。

2、段寄存器的引用

32位CPU內有6個段寄存器,程序在某一時刻可訪問6個不同的段。其段寄存器的值在不同的方式下具有不同的含義:

(1)在實方式下,段寄存器的值就是段地址;

(2)在保護方式下,段寄存器的值不是段地址,是段地址的“選擇器”。它間接指出一個32位的段地址。

下面分別說明各段寄存器的用法和作用。

代碼段寄存器:32位微機在取指令時,系統自動引用CS和EIP來取出下條指令。在實方式下,由於段的最大容量不超過64K,所以,EIP的高16位全為0,其效果相當於16位CPU中的IP。

堆棧段寄存器:32位微機在訪問堆棧段時,總是引用堆棧段寄存器SS。但在不同的方式下其堆棧指針有所不同:

1)、在實方式下,32位微機把ESP的低16位SP作為指向堆棧的指針,所以,我們可以認為棧頂單元是由SS和SP來指定的。這就與16位微機訪問棧頂單元的方法相一致;

2)、在保護方式下,堆棧指針可用32位的ESP和16位的SP。

數據段寄存器:DS是主要的數據段寄存器。通常情況下,它是除訪問堆棧以外數據時的默認段寄存器。在某些串操作中,其目的操作數的段寄存器被指定為ES是另一個例外。

另外,段寄存器CS、SS、ES、FS和GS也都可以作為訪問數據時的段寄存器,但它們必須用段超越前綴的方式在指令中直接寫出。用這種方式會增加指令的長度,指令的執行時間也有所延長。

一般來說,程序頻繁訪問的數據段用DS來指向,不太經常訪問的數據段可用ES、FS和GS等來指向。

3、存儲單元的內容

32位微機存儲單元內容的存儲格式與16位微機的完全一致,也都采用“高高低低”的原則來存放數據。

匯編語言--CPU資源和存儲器(二)