1. 程式人生 > 其它 >3.2 段設定偽指令ASSUME、如何裝入四個暫存器

3.2 段設定偽指令ASSUME、如何裝入四個暫存器

3.2 段設定偽指令ASSUME

作用

  • 告訴彙編程式,在處理源程式時,定義的段與哪個段暫存器關聯
  • ASSUME並不設定各個段暫存器的具體內容段暫存器的值是在程式執行時設定的。
  • 彙編時,只是關聯,未賦值。

使用

  • 在一個程式碼段中可以有幾條ASSUME偽指令,對於前面的設定,可以用ASSUME改變原來的設定。

  • 一條ASSUME語句不一定設定全部段暫存器,可以選擇其中一個或幾個段暫存器。

  • 可以使用關鍵字NOTHING將前面的設定刪除。

    • 例如:

    • ASSUME ES:NOTHING 	;刪除前面對ES與某個定義段的關聯
      ASSUME NOTHING		;刪除全部4個段暫存器的設定
      

格式

  • ASSUME 段暫存器名:段名,段暫存器名:段名,..........
    • 其中,段暫存器名為CS, DS,ES和SS四個之一
    • 段名是用SEGMENT╱ENDS偽指令定義的段名

DATA1 SEGMENT
	VAR1 DB 12H
DATA1 ENDS
DATA2 SEGMENT
	VAR2DB 34H
DATA2 ENDS
CODE SEGMENT
	VAR3 DB56H
	ASSUME CS:CODE,DS:DATA1,ES:DATA2	;這裡ASSUME來關聯
START:
	.....
	INC VAR1	;該指令彙編時,VAR1使用的是DS
	INC VAR2	;該指令被彙編時,VAR2使用的是ES,即指令編碼中有段字首ES
	INC VAR3	;該指令彙編時,VAR3使用的是CS,即指令編碼中有段字首CS
	......
CODE ENDS
	END START

四個段暫存器的裝入

  • 要讓一個段暫存器真正地指向某個邏輯段,就需要將段基值裝入到該段暫存器。
  • 段暫存器的裝入需要用程式的方法來實現。四個段暫存器的裝入方法略有不同

1.DS和ES的裝入

  • 在程式中,使用資料傳送語句來實現對DS和ES的裝入。
DATA1 SEGMENT
	DBYTE1 DB 12H
DATA1 ENDS
DATA2 SEGMENT
	DBYTE2 DB 14H DUP(?)
DATA2 ENDS

CODE SEGMENT
ASSUME CS:CODE,DS:DATA1	;關聯。
START: 	MOV AX,DATA1	;資料段DATA1放到暫存器AX
        MOV DS,AX		;資料段從AX放到DS
        MOV AX,DATA2	;資料段DATA2放到暫存器AX,但是前面並未關聯DATA2
        MOV ES,AX		;資料段從AX放到ES
        MOV AL,DBYTE1	;資料從DBYTE1放到AL
        MOV DBYTE2[2],AL	;該指令在彙編時出錯,因為在ASSUME指令中未指定ES與DATA2關聯
		……………
CODE ENDS

  • 在組合語言程式中,引用段名就是以立即數形式獲取該邏輯段的段基址
  • 而在MOV指令中,立即數不能直傳給段暫存器,所以給段暫存器的賦值必須經過一個通用的暫存器中轉再送入DS/ES

改正方法:

1、可以在變數DBYTE2前加一個段字首說明即可。即:

MOV ES:DBYTE2[2],AL

2、,最好的辦法是在ASUMME語句中,將ES與DATA2關聯。

2.SS的裝入:

有兩種方法

  • 1、(常用)段定義偽指令時,使用STACK引數並在段定址偽指令ASSUME語句中,把該段與SS段暫存器關聯
STACK1 SEGMENT PARA STACK	;這裡是使用了STACK引數
	DB 40H DUP(?)
STACK1 ENDS
	…………
CODE SEGMENT
	ASSUME CS:CODE,SS:STACK1 ;這裡是暫存器與段關聯了
	…………					;SS將被自動裝入STACK1段的段基值,堆疊指標SP也將指向堆疊底部+2的儲存單元。這裡(SP)=40H。
  • 2、在段定義偽指令時,未使用STACK引數,或者是在程式中要調換到另一個堆疊,使用類似於DS和ES的裝入方法。
DATA_STACK SEGMENT
	DB 40H DUP(?)
	TOP LABEL WORD ;TOP變數的偏移量為40H,即棧底+2,這裡是WORD,因為SP是按字操作的
DATA_STACK ENDS
	......
CODE SEGMENT
	......
	MOV AX,DATA_STACK
	MOV SS,AX
	MOV SP,OFFSET TOP
	......
	

3.CS的裝入:

如何裝入

  • CPU在執行指令之前根據CS和IP的內容來從記憶體中提取指令,即必須在程式執行之前裝入CS和IP的值
  • 因此, CS和IP的初始值就不能用可執行語句來裝入

格式

END 起始地址(段定義結束用:ENDS)	;起始地址:可以是一個標號或表示式
  • END偽指令用來指示源程式結束和指定程式執行時的起始地址
  • 當程式被裝入記憶體時,系統軟體根據起始地址段基值偏移量分別被裝入CS和IP中。
CODE SEGMENT
	ASSUME CS:CODE.....
START: .....	;這裡的起始地址就是標號START
CODE ENDS
	END START

裝入CS和IP一般有下面兩種情況。

1、由系統軟體按照結束偽指令指定的地址裝入初始的CS和IP,任何一個源程式都必須以END偽指令來結束。

2、在程式執行期間,當執行某些指令時,CPU自動修改CS和IP,使它們指向新的程式碼段,程式為非順序執行中的某些型別〈不包括條件轉移,迴圈等,它們是段內轉移)。

例如:

  • 執行段間過程呼叫CALL和段間返回指令RET;
  • 執行段間無條件轉移指令JMP;(段間轉移)
  • 響應中斷及中斷返回指令;
  • 執行硬體復位操作。
“朝著一個既定的方向去努力,就算沒有天賦,在時間的積累下應該也能稍稍有點成就吧。”