一、數據傳送類指令
- 通用傳送指令——MOV
- mov指令並非任意傳送:
- 源操作數和目的操作數不能同時為主存儲器操作數
-
MOV DBUF2,DBUF1 ;錯誤 MOV AX,DBUF1 MOV DBUF2,AX ;正確
-
- 源操作數和目的操作數不能同時為段寄存器操作數
- 立即數不能直接傳送給段寄存器
-
MOV DS, @DATA ;錯誤 MOV AX,@DATA MOV DS,AX ;正確
-
- 傳送時雙操作數必須類型一致
-
MOV SI,DL ;錯誤:類型不一致 SI16位,DL8位 MOV AL,050AH ;錯誤:類型不一致 050AH超過AL范圍
-
- 操作數必須要有明確的類型
-
MOV [BX],255 ;錯誤:無明確類型 MOV BYTE PTR [BX] , 255 ;正確,byte ptr說明是字節操作
-
- 源操作數和目的操作數不能同時為主存儲器操作數
- mov指令並非任意傳送:
- 通用傳送指令——XCHG
- 將源操作數和目的操作數的內容交換
- 可以使用於通用寄存器與通用寄存器之間或者通用存儲器與存儲器之間
- 例子:
XCHG SI,DI XCHG SI,[DI] XCHG AL,BVAR
- 空操作指令NOP(=XCHG AX,AX)
- 例子:
- 堆棧操作指令
- 只有一個數據出入口——當前棧頂
- 兩種基本操作
- push
- SP-2作為當前棧頂
- 將源操作數(通用寄存器/段寄存內容/存儲器操作數)傳送到棧頂
- 以字為單位進行操作
- pop
- SP+2作為當前棧頂
- 將棧頂數據傳送到目的操作數(通用寄存器/段寄存內容/存儲器操作數)
- 以字為單位進行操作
- push
- SS指向堆棧段的起始位置(段基地址) SP指定棧頂
- 數據進入堆棧,SP逐漸減小
- 數據依次彈除,SP逐漸增大
- 堆棧的應用
- 堆棧操作指令
- 子程序調用CALL和返回RET
- 中斷調用INT和返回IRET
- 內部異常、外部中斷
- 存放臨時數據,以便隨時恢復
- 子程序的寄存器的保護和恢復
- 地址傳送指令
- 獲取存儲器操作數的地址
- 格式:LEA R16,MEM
- 類似OFFSET的作用
- LEA在指令執行時計算出偏移地址
- OFFSET操作符在匯編階段取得變量的偏移地址
- OFFSET無需在執行時計算,執行速度更快
- LEA能獲取匯編階段無法確定的偏移地址
- 例:
LEA SI,VAR MOV DI,OFFSET VAR ;等價
LEA DX,[BX+DI-100H] ;先進行加法運算得到偏移地址再傳送給DX寄存器(相對基址變址尋址方式) MOV DX,OFFSET[BX+DI-100H] ;是錯誤的,因為匯編時不知道執行DX和DI等於什么
- 其他的:指針傳送指令LDS和LES,能將主存連續四個字節內容的前兩個分別傳送給DS和ES后續字節作為偏移地址傳送給指令的十六位通用寄存器。
- 換碼指令
- XLAT指令功能:AL←[BX+AL]
- 指令執行前:
- 在主存建立一個字節量表格
- 表格首地址放於BX
- AL存放相對表格首地址的位移量
- 指令執行后:
- 將AL寄存器的內容轉換為目標代碼
- 指令執行前:
- 例:
;eg303.asm .model small .stack .data num db 6,7,7,8,3,0,0,0 tab db '0123456789' ;代碼表 .code .startup mov cx,lengthof num ;CX等於要轉換數字的個數 mov si,offset num ;SI指向要轉換的數字 mov bx,offset tab ;BX指向代碼表 again: mov al,[si] ;AL←要轉換的數字 xlat ;換碼,AL得到數字的ASCII值 mov dl,al ;顯示 mov ah,2 int 21h add si,1 ;指向下一個數字 loop again ;循環 .exit end
- XLAT指令功能:AL←[BX+AL]
- 標志傳送指令
- 可以直接改變CF、DF、IF狀態的標志位操作指令
- 教材P73
- 輸入輸出指令
- 輸入指令IN:數據從IO接口輸入到微處理器
- IN AL,21H
- IN AL,DX
- 輸出指令OUT:數據從微處理器輸出IO接口
- OUT 21H,AL
- OUT DX,AL
- IO尋址方式:直接尋址&DX間接尋址
- 直接尋址由IO指令直接提供8位IO地址 只能尋址最低256個IO地址 用i8表示
- 間接尋址用DX寄存器保存訪問的IO地址 可以尋址全部IO地址(0000~FFFFH) 直接寫成DX,表示IO地址
- 8位IO傳輸:IO指令使用AL
- 16位IO傳輸:IO指令使用AX
- 輸入指令IN:數據從IO接口輸入到微處理器
二、算數運算類指令
- 狀態標志
- CF 進位標志 針對無符號數
- 當加減法運算結果的最高有效位有進位或借位 CF=1
- N個二進制位表達無符號整數的范圍:0~pow(2,N)-1
- 有進位加上進位或借位后結果仍然正確
- OF 溢出標志 針對有符號數
- 加減結果有溢出 OF=1
- N個二進制位(補碼)表達有符號整數的范圍:-pow(2,N-1)~pow(2,N-1)-1
- 有溢出,運算結果已經不正確
- 判斷:
- 最高位和次高位同時有進位或同時無進位,無溢出;最高位和次高位進位狀態不同,有溢出
- 只有兩個相同符號數數相加(或兩個不同符號數相減),而運算結果的符號與原數據符號相反時產生溢出,其他情況無溢出。
- ZF 零標志
- 運算結果位0,ZF=1
- SF 符號標志
- 運算結果最高位為1,SF=1
- PF 奇偶標志
- 運算結果最低字節(最低8位)中“1”的個數為零或偶數,PF=1
- AF 輔助進位標志/調整標志
- 最低半字節有進位或借位時,AF=1
- 查看狀態標志方法:
-
PUSHF;將標志寄存器的值入棧 POP AX;將標志寄存器的值出棧賦值給AX
-
- CF 進位標志 針對無符號數
- 加法指令
- ADD
- 雙操作數。目的操作數加上源操作數,和送回目的操作數
- 按照定義影響六個狀態標志位
- ADC
- 兩個操作數相加再加CF,結果送回目的操作數
- 按照定義影響六個標志位
- INC
- 一個操作數,實現對操作數自增一,再將結果返回原處
- 不影響CF,但影響其他標志位
- ADD
- 減法指令
- SUB
- 目的操作數減去源操作數,結果送回目的操作數
- 按照定義影響六個標志位
- SBB
- 除完成SUB減法運算外,還要減去借位CF,結果送回目的操作數
- 按照定義影響六個標志位
- DEC
- 對操作數減一再將結果返回原處
- 不影響CF,但影響其他標志位
- NEG
- 求補指令 單操作數
- 用零減去操作數,將結果返回操作數
- 按照定義影響六個標志位
- CMP
- 將目的操作數減去源操作數,差值不送回。
- 按照減法結果影響標志
- SUB
- 乘法指令
- MUL/IMUL(無符號數/有符號數)
- 隱含使用目的操作數AX
- 源操作數為8位數:AL與其相乘得到16位積,存入AX
- 源操作數為16位:AX與其相乘得到32位積,高16位存入DX,低16位存入AX
- 對標志的影響:
- 若乘積的高一半是低一半的符號位擴展,說明高一半不含有效數值,則OF=CF=0
- 若高一半有效,則OF=CF=1
- 乘法指令對其他標志狀態沒有定義,即為任意,不可預測
- MUL/IMUL(無符號數/有符號數)
- 除法指令
- DIV/IDIV(無符號數/有符號數)
- 隱含使用目的操作數AX
- 8位除法:AL=AX÷源操作數的商,AH=AX÷源操作數的余數
- 16位除法:AX=DX.AX÷源操作數的商,DX=DX.AX÷源操作數的余數
- DIV/IDIV(無符號數/有符號數)
- 符號擴展指令
- CBW :AL擴展到AX
- CWD:AX擴展到DX.AX
三、位操作類指令
- 邏輯運算指令
- AND
- 同0與 復位
- OR
- 同1或 置位
- NOT
- XOR
- “與1異或取反,與0異或不變”
- 最快的將寄存器清零的方法:XOR DX,DX
- TEST
- 將兩個操作數按位進行邏輯與運算,不返回邏輯與的結果,根據結果像AND指令一樣設置狀態標志。
- 除NOT不影響標志外,其他邏輯指令講OF=CF=0,按定義影響ZF、SF、PF
- AND
- 移位指令
- 移位
- shl 邏輯左移:左移1/CL位,最低位補零,最高位進入CF
-
;AL=1111 0101B SHL AL,1 ;AL=1110 1010B CF=1 ;OF=0
-
- shr 邏輯右移:右移1/CL位,最高位補零,最低位進入CF
-
;AL=1111 0101B SHR AL,1 ;AL=0111 1010B ;CF=1 OF=1
-
- sal 同shl
- sar 算數右移:右移1/CL位,最高位不變,最低為進入CF
-
;AL=1111 0101B SAR AL,1 ;AL=1111 1010B ;CF=1 OF=0
-
- 源操作數只能是1或者CL
- 根據最高或最低位移處的位設置CF
- 根據移位后的結果影響SF,ZF,PF
- 如果進行一位移動,按照操作數的最高符號是否改變設置溢出標志OF:
- 移位前最高位與移位后最高位不同:OF=1
- 移位次數不為1時OF不確定。
- 邏輯左移相當於乘二,邏輯右移相當於除二。 商在操作數中,余數由CF標志反映。
- shl 邏輯左移:左移1/CL位,最低位補零,最高位進入CF
- 循環移位
- rol 不帶進位循環左移:左移1/CL位,最高位進入CF和最低位
-
;AL=1110 0101B ROL AL,1 ;AL=1100 1011 ;CF=1 OF=0
-
- ror 不帶進位循環右移:右移1/CL位,最低位進入CF和最高位
-
;AL=1110 0101B CL=2 ROR AL,CL ;AL=0111 1001B ;CF=0
-
- rcl 帶進位循環左移:左移1/CL位,最高位進入CF,CF進入最低位
-
;AL=1110 0101B CF=0 RCL AL,1 ;AL=1100 1010B ;CF=1 OF=0
-
- rcr 帶進位循環右移:右移1/CL位,最低位進入CF,CF進入最高位
-
;AL=1110 0101B CL=4 CF=0 RCR AL,CL ;1 AL=0111 0010B CF=1 ;2 AL=1011 1001B CF=0 ;3 AL=0101 1100B CF=1 ;4 AL=1010 1110B CF=0
-
- rol 不帶進位循環左移:左移1/CL位,最高位進入CF和最低位
- 移位
四、課后習題!
3.1 (1)如何修改"MOV SI,BYTE PTR 250"語句使其正確?
MOV SI,250
(2)為什么說“XCHG DX,CL"是一條錯誤的指令?
源寄存器操作數和目的寄存器操作數位數不同。
(5)執行了一條加法指令后,發現ZF=1,說明結果是什么?
0
(7)大小寫字母轉換使用了什么規律?
相差20H。
(9)除法指令”DIV SI"的被除數是什么?
被除數32位,DX保存高16位,AX保存低16位。
3.2 判斷題
(1)指令“MOV AX,0”使AX結果為0,所以標志位ZF=1。
錯,MOV XCHG不影響標志位
(4)雖然ADD指令和SUB指令執行后會影響標志狀態,但執行前的標志並不影響它們的執行結果。
對。
(5)80-90需要借位,所以執行結束后,進位標志CF=1.
對。
(7)無符號數在前面加零擴展,數值不變;有符號數前面進行符號擴展,位數加長一位,數值增加一倍。
錯。符號擴展不改變數值大小。有符號數的符號擴展擴展的是符號位。
(10)SHL指令左移一位,就是乘10.
錯。是*2。
3.3 填空題
(1)指令"PUSH DX"執行后,SP -2 。
(2)指令"POP DX"的功能是將堆棧頂部的數據傳送給 DX ,然后 SP+2 。
(4)進行8位的二進制數加法BAH+6CH,8位結果是 26H ,標志PF= 0 。如果進行16位二進制數加法45BAH+786CH,16位結果是 0BE26 ,標志PF= 0 。
(5)假設AX=98H,執行NEG AX指令后,AX= 0FF68H ,標志SF= 1 。
(8)指令“XOR AX,AX”和“SUB AX,AX”執行后,AX= 0 。CF=OF= 0 。而指令"MOV AX,0"執行后,AX= 0 ,CF和OF沒有變化。
(10)欲將DX內的無符號數除以16,可以使用指令"SHR DX, CL ",其中后一個操作數是一個8位寄存器,其值等於 4 。
3.5 操作數的組合通常符合邏輯,但不是任意的,指出下列指令的錯誤原因:
(1)MOV CX,DL 位數不同(類型不匹配)
(2)MOV IP,AX IP為專用寄存器,不能賦值
(3)MOV ES,1234H 不能直接將立即數賦值給段寄存器
(4)MOV ES,DS 段寄存器之間不能賦值
(5)MOV AL,300 位數不同
(6)MOV [SI],45H 沒有明確類型
(7)MOV AX,BX+DI 無該種尋址方式
(8)MOV 20H,AH 不能給立即數賦值
3.6 使用MOV指令實現交換指令“XCHG BX,[DI]”功能。
MOV AX,[DI]
MOV BX,AX
MOV [DI],BX
3.11 分別執行如下程序片段,說明每條指令的執行結果:
(1)
MOV AX,80H ;AX= 0080H ADD AX,3 ;AX= 0083H ,CF= 0 ,SF= 0 ADD AX,80H ;AX= 0103H ,CF= 0 ,OF= 0
ADC AX,3 ;AX= 0106H ,CF= 0 ,ZF= 0
(2)
MOV AX,100 ;AX= 64H ADD AX,200 ;AX= 12CH ,CF= 0
(3)
MOV AX,100 ;AX= 64H ADD AL,200 ;AX= 2CH ,CF= 1
(4)
MOV AL,7FH ;AL= 7FH SUB AL,8 ;AL= 77H ,CF= 0 ,SF= 0 SUB AL,80H ;AL= F7H ,CF= 1 ,OF= 1 SBB AL,3 ;AL= F3H ,CF= 0 ,ZF= 0
3.14 請分別用一條匯編語言指令完成如下功能:
(1)把BX寄存器和DX寄存器的內容相加,結果存入DX寄存器
ADD DX,BX
(2)用寄存器BX和SI的基址變址尋址方式把存儲器中的一個字節和AL寄存器的內容相加,並把結果送到AL中。
ADD AL, [BX+SI]
(3)用BX和位移量0B2H的寄存器相對尋址方式把存儲器中的一個字和CX寄存器的內容相加,並把結果送回存儲器中。
ADD [BX+0B2H],CX
(4)將16為變量VARW與數3412H相加,並把結果送回該存儲單元中。
ADD VARW,3412H
(5)把數0A0H與AX寄存器的內容相加,並把結果送回AX中。
ADD AX,0A0H
3.16 分別執行如下程序片段,說明每條指令的執行結果:
(1)
MOV SI,10011100B ;SI= 9C H AND SI,80H ;SI= 80 H OR SI,7FH ;SI= FF H XOR SI,0FEH ;SI= 1 H
(2)
MOV AX,1010B ;AX= 0000 0000 0000 1010 B MOV CL,2 SHR AX,CL ;AX= 0000 0000 0000 0010 B,CF= 1 SHL AX,1 ;AX= 0000 0000 0000 0100 B,CF= 0 AND AX,3 ;AX= 0000 0000 0000 0000 B,CF= 0
(3)
MOV AX,1011B ;AX= 0000 0000 0000 1011 B MOV CL,2 ROL AX,CL ;AX= 0000 0000 0010 1100B,CF= 0 RCR AX,1 ;AX= 0000 0000 0001 0110 B,CF= 0 OR AX,3 ;AX= 0000 0000 0001 0111 B,CF= 0
(4)
XOR AX,AX ;AX= 0 ,CF= 0 ,OF= 0 ;ZF= 1 ,SF= 0 ,PF= 1
3.21 如下程序片段實現AX乘以某個數X的功能,請判斷X=?請使用一條乘法指令實現上述功能。
MOV SI,AX SHL SI,1 SHL SI,1 SHL SI,1 SUB SI,AX MOV AX,SI
答:本程序段相當於:AX*2*2*2-AX=AX*7
故X=7
使用一條乘法指令為:
mul ax,7
3.22請使用移位和減法指令編寫一個程序片段計算:AX×21,假設乘積不超過16位。(提示:21=pow(2,4)+pow(2,2)+pow(2,0))。
答:
MOV SI,AX SHL SI,1 SHL SI,1 ADD AX,SI SHL SI,1 SHL SI,1 ADD AX,SI