8086指令系統採用了一種靈活的, 由1-6個字節組成的變字長的指令格式, 包括操作碼, 尋址方式以及操作數三個部分
1.指令格式
通常指令的第一字節爲操作碼字節(OPCODE), 規定指令的操作類型. 第二字節爲尋址方式字節(MOD), 規定操作數的尋址方式; 接着以後的3-6字節依據指令的不同而取捨
第一字節爲操作碼, 它指出指令所要進行的操作. 其中
- W指示操作數類型 : W=0爲字節, W=1爲字;
- D指示REG操作數的傳送方向: D=0表示REG操作數爲源操作數, D=1表示REG操作數爲目的操作數
第二字節爲尋址方式, 它指出所用的兩個操作數存放的位置.其中 :
-
REG字段規定一個寄存器操作數, 它作爲源操作數還是目的操作數已由第一個字節中的D位規定.
-
MOD字段用來區分另一個操作數在寄存器中(寄存器尋址)還是在存儲器中(存儲器尋址), 在存儲器尋址的情況下, 還用來指出該字節後面有無偏移量, 有多少偏移量
-
R/M字段受MOD字段控制; 若MOD=11爲寄存器方式, R/M字段將指出第二操作數所在寄存器編號; MOD=00,01,10爲存儲器方式R/M則指出如何計算計算機存儲器中操作數的偏移地址.
2.8086指令的尋址方式
1> 操作數的種類
指令中操作的對象稱爲操作數. 8086指令中操作數的種類分爲數據操作數和地址操作數兩種
(1)數據操作數
數據操作數與數據有關的操作數,即指令中操作的對象是數據, 可以分爲
- 立即數操作數, 即指令中要操作的數包含在指令中
- 寄存器操作數, 即指令中要操作的數據存放在指定的寄存器中
- 存儲器操作數,即指令中要操作的數據存放在指定的存儲單元中
- I/O操作數,即指令中要操作的數據來自或送到I/O端口
(2)地址操作數
地址操作數是與程序轉移地址有關的操作數. 即指令中操作的對象不是數據, 而是要轉移的目標地址, 其也可以分爲上面的幾種種類, 分別代表其存儲位置的地址
對於數據操作數,有的指令有兩個操作數, 一個叫源操作數, 一個叫目的操作數. 有的只有一個操作數. 有的沒有操作數, 有的指令有一個隱含或兩個隱含操作數
對於地址操作數, 指令只有一目的操作數, 它是一個供程序轉移的目標地址
2>尋址方式
所謂尋址方式, 就是指令中所給出的尋找操作數(包括數據操作數和地址操作數)的方法
(1)數據尋址方式
-
立即數尋址方式: 所提供的操作數直接包含在指令中,緊跟在操作碼之後,這種操作數稱爲立即數, 例如:
MOV BL, 80H MOV AX, 1090H
-
寄存器尋址方式
寄存器尋址方式的操作數存放在指令規定的寄存器中, 寄存器的名字在指令中指出.例如
MOV CL, DL MOV AX, BX
-
存儲器尋址方式
存儲器尋址方式的操作數都存放在存儲單元中, 而操作數在存儲器中的物理地址是由段地址左移4位與操作數在段內偏移地址相加得到的. 段地址在實模式和保護模式下可以通過不同途徑取得. 那我們是如何取得段內偏移地址(有效地址),有效地址可以由以下三種地址分量組成
1.位移量,一個8位或16位的數,是一個地址
2.基址:存放在基址寄存器BX或BP中的內容
3.變址:存放在變址寄存器中SI或DI中的內容
//1.直接尋址方式,只包含位移量一種分量(默認段地址爲DS) MOV AL, [1064H] //也可以修改數據段 MOV AL, ES:[1064H] //2.寄存器間接尋址方式 /** 寄存器間接尋址方式的操作數有效地址只包含基址寄存器(BX)的內容或變址寄存器(SI,DI)的內容一種分量 操作數的有效地址在某個寄存器中, 而操作數本身則在存儲器的數據段內 默認段寄存器:DS(數據段寄存器) */ MOV AX, [SI] MOV [BX], AL //越段 MOV ES:[DI], AX //3.寄存器相對尋址方式 //其實就是在寄存器簡介尋址的基礎上, 可以使用基址寄存器BP,並且可以與給定的8位或16位位移量相加 //BX,SI,DI默認段寄存器爲DS; BP默認段寄存器是SS MOV [SI+10H], AX MOV CX, [BX+COUNT] //也可以像下面這樣書寫 MOV AL, [BP+TABLE]; MOV AL, [BP]+TABLE; MOV TABLE[BP] //4.基址變址尋址方式 //基址變址尋址方式的操作數有效地址是一個基址寄存器(BX或BP)和一個變址寄存器(SI或DI)的內容之和 //BX對應數據段DS BP對應堆棧段SS MOV [BX+DI], AX MOV AH, [BP][SI] //5.基址變址相對尋址方式 //在基址變址尋址方式的基礎上加上了一個8位或16位的位移量 MOV AX, [BX+SI+COUNT] MOV AX, [BX][SI+COUNT] MOV AX, [BX][SI]+COUNT MOV AX, [BX+SI]+COUNT MOV AX, [BX][SI]COUNT
-
I/O端口尋址方式
1.端口直接尋址方式
這種尋址方式的端口地址用8位立即數表示,例如
IN AL, 21H
表示從地址爲21H的端口中讀取數據送到AL中
2.端口間接尋址方式
當I/O端口地址大於FFH時,必須事先將端口地址存放在DX寄存器中, 例如
MOV DX, 120H OUT DX, AX
(2)地址尋址方式
在8086指令系統中,有一組指令被用來控制程序的執行順序. 程序的執行順序是由CS和IP的內容所決定的. 通常情況下,BIU完成一次取指令週期後, 就自動改變IP的內容以指向下一條指令的地址, 使程序按預先存放在程序存儲器中的指令的次序, 從低地址到高地址順序執行. 如果要改變程序的執行順序, 轉移到所要求的指令地址再順序執行, 可以安排一條程序轉移指令,並按指令的要求修改IP內容或者同時修改IP和CS的內容.
轉移地址可以在段內,也可以跨段.尋求轉移地址的方法稱爲地址尋址方式
-
段內直接尋址方式
也稱爲相對尋址方式,轉移的地址是(IP+一個8位或16位的相對位移量). 這個位移量是下一條指令到目標地址之間的相對位移量, 例如
//PROGIA和QUEST都是轉向的目標地址,用位移量表示 //位移量爲16位的寫法,近轉移 JMP NEAR PTR PROGIA //位移量爲8位的寫法,短轉移 JMP SHORT QUEST
-
段內間接尋址方式
程序的轉移地址存放在寄存器或存儲單元中, 用指定的寄存器或存儲器中的值取代當前IP的內容.
這條指令和後面的兩個段間尋址方式都不能用於條件轉移指令,也就是說條件轉移指令只能使用段內直接尋址的8位位移量
JMP BX //WORD PTR表示氣候所取得的地址是一個字的有效地址 JMP WORD PTR [BP+TABLE]
-
段間直接尋址方式
這種尋址方式是在指令中直接給出16位的段地址和16位的偏移地址用來更新當前的CS和IP的內容,例如
//LABEL_NAME是一個在另外的代碼段內已經定義的遠標號,作用是用標號的偏移地址取代IP,段地址取代CS JMP LABEL_NAME //利用運算符標號FAR將NEXTROUTINT的屬性定義爲FAR JMP FAR PTR NEXTROUTINT
-
段間簡介尋址方式
由指令中給出的存儲器尋址方式求出存放轉移地址的四個連續內存單元; 前兩個單元送給IP, 後兩個單元送給CS
//VAR_DOUBLEWORD是一個已經定義爲32位的存儲器變量 JMP VAR_DOUBLEWORD //運算符PTR將操作數的類型定義爲DWORD(雙字) JMP DWORD PTR[BP][DI]