?? 匯005.txt
字號:
圖5.16 置字符串數(shù)據(jù)指令的功能示意圖
3、字符串傳送指令(Move String Instruction)
該指令是把指針DS:SI所指向的字節(jié)、字或雙字傳送給指針ES:DI所指向內(nèi)存單元,并根據(jù)標志位DF對寄存器DI和SI作相應增減。該指令的執(zhí)行不影響任何標志位。
指令的格式:MOVS 地址表達式1, 地址表達式2
MOVSB/MOVSW
MOVSD ;80386+
圖5.17 字符串傳送指令的功能示意圖
4、輸入字符串指令(Input String Instruction)
該指令是從某一指定的端口接受一個字符串,并存入一片存儲單元之中。輸入端口由DX指定,存儲單元的首地址和讀入數(shù)據(jù)的個數(shù)分別由ES:DI和CX來確定。在指令的執(zhí)行過程中,還根據(jù)標志位DF對寄存器DI作相應增減。該指令不影響任何標志位。
與指令有關的操作數(shù)ES、DI、DX和CX等都是隱含操作數(shù)。
指令的格式:INS 地址表達式
INSB/INSW
INSD ;80286+
5、輸出字符串指令(Output String Instruction)
該指令是把一個字符串輸入到指定的輸出端口中。輸出端口由DX指定,其輸出數(shù)據(jù)的首地址和個數(shù)分別由DS:SI和CX來確定。在指令的執(zhí)行過程中,還根據(jù)標志位DF對寄存器SI作相應增減。該指令的執(zhí)行不影響任何標志位。
與指令有關的操作數(shù)DS、SI、DX和CX等都是隱含操作數(shù)。
指令的格式:OUTS 地址表達式
OUTSB/OUTSW
OUTSD ;80286+
6、字符串比較指令(Compare String Instruction)
該指令是把指針DS:SI和ES:DI所指向字節(jié)、字或雙字的值相減,并用所得到的差來設置有關的標志位。與此同時,變址寄存器SI和DI也將根據(jù)標志位DF的值作相應增減。
指令的格式:CMPS 地址表達式1, 地址表達式2
CMPSB/CMPSW
CMPSD ;80386+
受影響的標志位:AF、CF、OF、PF、SF和ZF
圖5.18 字符串比較指令的功能示意圖
7、字符串掃描指令(Scan String Instruction)
該指令是用指針ES:DI所指向字節(jié)、字或雙字的值與相應的AL、AX或EAX的值相減,用所得到的差來設置有關標志位。與此同時,變址寄存器DI還將根據(jù)標志位DF的值進行增減。
指令的格式:SCAS 地址表達式1
SCASB/SCASW
SCASD ;80386+
受影響的標志位:AF、CF、OF、PF、SF和ZF
8、重復字符串操作指令(Repeat String Instruction)
前面介紹了七種不同的字符串操作指令:取字符串數(shù)據(jù)、置字符串數(shù)據(jù)、字符串傳送、輸入字符串、輸出字符串、字符串比較和字符串掃描等指令,所敘述是這些指令執(zhí)行一次所具有的功能。但我們知道:每個字符串通常會有多個字符的,所以,就需要重復執(zhí)行這些字符串操作指令。為了滿足這種需求,指令系統(tǒng)提供了一組重復前綴指令。
雖然在這些字符串指令的前面都可以添加一個重復前綴指令,但由于指令執(zhí)行結(jié)果的差異,對某個具體的字符串指令又不用重復前綴指令而改用其它循環(huán)來實現(xiàn)重復的需要。
重復字符串操作指令對標志位的影響是由被重復的字符串操作指令來決定。
重復前綴指令REP(Repeat String Instruction)
重復前綴指令是重復其后的字符串操作指令,重復的次數(shù)由CX來決定。其一般格式為:
REP LODS/LODSB/LODSW/LODSD
REP STOS/STOSB/STOSW/STOSD
REP MOVS/MOVSB/MOVSW/MOVSD
REP INS/ INSB/INSW/INSD
REP OUTS/OUTSB/OUTSW/OUTSD
重復前綴指令的執(zhí)行步驟如下:
(1)、判斷:CX=0;
(2)、如果CX=0,則結(jié)束重復操作,執(zhí)行程序中的下一條指令;
(3)、否則,CX=CX-1(不影響有關標志位),并執(zhí)行其后的字符串操作指令,在該指令執(zhí)行完后,再轉(zhuǎn)到步驟(1)。
從上面的重復前綴指令格式來看,雖然我們可以使用重復取字符串數(shù)據(jù)指令(第一組指令),但可能會因為指令的執(zhí)行結(jié)果而在程序中幾乎不被使用。
例5.20 編寫一段程序,計算字符串“12345abcdefgh”中字符的ASCII之和。
解:
…
MESS DB '12345abcdefgh' ;在數(shù)據(jù)段中進行變量說明
…
MOV AX, SEG MESS
MOV DS, AX
LEA SI, MESS ;用DS:SI來指向字符串的首地址
MOV CX, 13D ;重復次數(shù)
XOR BX, BX ;置求和的初值為0
REP LODSB
…
雖然指令“REP LODSB”能從字符串中取出每個字符,但它是在一條指令中完成的,程序的其它指令根本無法處理每次取出的數(shù)據(jù),指令的執(zhí)行結(jié)果是:AL只保存最后一次所取出的字符'h'的ASCII碼。
所以,為了實現(xiàn)本例的要求,不能使用重復前綴指令,而要把指令“REP LODSB”改寫成如下四條指令:
XOR AH, AH ;為后面的累加作準備
again: LODSB
ADD BX, AX ;AL是被取出的字符,AH已被清0
LOOP again
條件重復前綴指令(Repeat String Conditionally)
條件重復前綴指令與前面的重復前綴指令功能相類似,所不同的是:其重復次數(shù)不僅由CX來決定,而且還會由標志位ZF來決定。根據(jù)ZF所起的作用又分為二種:相等重復前綴指令REPE/REPZ和不等重復前綴指令REPE/REPZ。
A、相等重復前綴指令的一般格式為:
REPE/REPZ SCAS/SCASB/SCASW/SCASD
REPE/REPZ CMPS/CMPSB/CMPSW/CMPSD
該重復前綴指令的執(zhí)行步驟如下:
(1)、判斷條件:CX≠0 且 ZF=1;
(2)、如果條件不成立,則結(jié)束重復操作,執(zhí)行程序中的下一條指令;
(3)、否則,CX=CX-1(不影響有關標志位),并執(zhí)行其后的字符串操作指令,在該指令執(zhí)行完后,再轉(zhuǎn)到步驟(1)。
B、不等重復前綴指令的一般格式為:
REPNE/REPNZ SCAS/SCASB/SCASW/SCASD
REPNE/REPNZ CMPS/CMPSB/CMPSW/CMPSD
該重復前綴指令的執(zhí)行步驟如下:
(1)、判斷條件:CX≠0 且 ZF=0;
(2)、如果條件不成立,則結(jié)束重復操作,執(zhí)行程序中的下一條指令;
(3)、否則,CX=CX-1(不影響有關標志位),并執(zhí)行其后的字符串操作指令,在該指令執(zhí)行完后,再轉(zhuǎn)到步驟(1)。
5.2.12 ASCII--BCD碼運算調(diào)整指令
前面介紹的算術運算指令都是針對二進制數(shù)進行操作的指令,但對絕大多數(shù)人來說,十進制是最簡單、熟悉的。為了方便按十進制數(shù)進行算術運算,指令系統(tǒng)專門提供了一組十進制運算調(diào)整指令。
雖然人們會覺得按十進制進行算術運算很自然,但計算機要化更多的時間來完成相應操作。在通常情況下,這組指令很少被程序員運用在實際的程序之中。所以,這組指令的使用率較低,可以根據(jù)需要有選擇性地學習。
1、ASCII碼加調(diào)整指令AAA(Ascii Adjust After Addition)
該指令是用于調(diào)整AL之值,該值是二個ASCII碼字節(jié)相加之和。具體的調(diào)整規(guī)則如下:
、若AL的低四位大于9,或標志位AF=1,則,AH=AH+1,AL=AL+6,并置AF和CF為1,否則,只置AF和CF為0;
、清除AL的高四位。
圖5.20 AAA指令執(zhí)行過程示意圖
指令的格式:AAA
受影響的標志位:AF和CF(OF、PF、SF和ZF等都是無定義)
例5.21 編寫一段程序,完成二個15位十進制數(shù)X和Y之和,并把計算結(jié)果存入X之中。假設數(shù)據(jù)X和Y都是以字符串形式表示的。
解:
…
X db "456407983123186" ;任意假設二個15位的大數(shù)
Y db "326676709587211"
…
CLC
MOV SI, 14 ;用變址寄存器SI來從字符串的后面向前訪問
MOV CX, 15 ;因為它們是二個15位十進制數(shù)
loop1: MOV AL, X[SI]
ADC AL, Y[SI] ;把被加數(shù)加上
AAA
MOV X[SI], AL
DEC SI
LOOP loop1 ;15位十進制數(shù)相加完畢
LEA BX, X ;下面5條指令是把X中的數(shù)據(jù)變成對應的字符
MOV CX, 15
loop2: ADD byte ptr [BX], '0'
INC BX
LOOP loop2
…
從上例可以看出,其實任意位的十進制數(shù)也都是可以的,只要改變CX的值即可。
2、ASCII碼減調(diào)整指令AAS(Ascii Adjust After Subtraction)
該指令是用于調(diào)整AL之值,該值是二個ASCII碼字節(jié)相減之差。具體的調(diào)整規(guī)則如下:
、若AL的低四位大于9,或標志位CF=1,則,AH=AH-1,AL=AL-6,并置AF和CF為1,否則,只置AF和CF為0;
、清除AL的高四位。
指令的格式:AAS
受影響的標志位:AF和CF(OF、PF、SF和ZF等都是無定義)
圖5.21 AAS指令執(zhí)行過程示意圖
3、ASCII碼乘調(diào)整指令AAM(Ascii Adjust After Multiplication)
該指令是用于調(diào)整寄存器AL之值,該值是由二個單BCD碼字節(jié)用無符號乘指令MUL所得的積。其調(diào)整規(guī)則如下:
AH←AL/10(商),AL←AL%10(余數(shù))
指令的格式:AAM
受影響的標志位:PF、SF和ZF(AF、CF和OF等都是無定義)
例如:
MOV AL, 9
MOV BL, 8
MUL BL ;AL=72D
AAM ;AH=7, AL=2
4、ASCII碼除調(diào)整指令AAD(Ascii Adjust After Division)
該指令是在作除法前用于調(diào)整寄存器AH和AL之值,它是把二個寄存器中單BCD碼組成一個十進制數(shù)值,為下面的除法作準備的。其調(diào)整規(guī)則如下:
AL←AH*10+AL,AH←0
指令的格式:AAD
受影響的標志位:PF、SF和ZF(AF、CF和OF等都是無定義)
例如:
MOV AX, 0502H
MOV BL, 10D
AAD ;AH=0, AL=52D
DIV BL ;AH=2(余數(shù)), AL=5(商)
5、十進制數(shù)加調(diào)整指令DAA(Decimal Adjust After Addition)
該指令是用于調(diào)整AL的值,該值是由指令ADD或ADC運算二個壓縮型BCD碼所得到的結(jié)果。壓縮型BCD碼是一個字節(jié)存放二個BCD碼,低四位和高四位都是一個BCD碼。
其調(diào)整規(guī)則如下:
、如果AL的低四位大于9,或標志位AF=1,那么,AL=AL+6,并置AF=1;
、如果AL的高四位大于9,或CF=1,那么,AL=AL+60H,并置CF=1;
、如果以上兩點都不成立,則,清除標志位AF和CF。
經(jīng)過調(diào)整后,AL的值仍是壓縮型BCD碼,即:二個壓縮型BCD碼相加,并進行調(diào)整后,得到的結(jié)果還是壓縮型BCD碼。
指令的格式:DAA
受影響的標志位:AF、CF、PF、SF和ZF(OF無定義)
例如:
MOV AL, 43H
MOV BL, 29H
ADD AL, BL ;AL=6BH,其不是壓縮型的BCD碼,因為低四位'B'不是BCD碼
DAA ;調(diào)整后,AL=72H,這是壓縮型的BCD碼,也有:43+29=72
6、十進制數(shù)減調(diào)整指令DAS(Decimal Adjust After Subtraction)
該指令也是用于調(diào)整AL的值,該值是由指令SUB或SBB運算二個壓縮型BCD碼所得到的結(jié)果。其調(diào)整規(guī)則如下:
、如果AL的低四位大于9,或標志位AF=1,那么,AL=AL-6,并置AF=1;
、如果AL的高四位大于9,或CF=1,那么,AL=AL-60H,并置CF=1;
、如果以上兩點都不成立,則,清除標志位AF和CF。
經(jīng)過調(diào)整后,AL的值仍是壓縮型BCD碼,即:二個壓縮型BCD碼相減,并進行調(diào)整后,得到的結(jié)果還是壓縮型BCD碼。
指令的格式:DAS
受影響的標志位:AF、CF、PF、SF和ZF(OF無定義)
例如:
MOV AL, 43H
MOV BL, 29H
SUB AL, BL ;AL=1AH,其不是壓縮型的BCD碼,因為低四位'A'不是BCD碼
DAS ;調(diào)整后,AL=14H,這是壓縮型的BCD碼,也有:43-29=14
5.2.13 處理器指令
處理器指令是一組控制CPU工作方式的指令。這組指令的使用頻率不高。
1、空操作指令NOP(No Operation Instruction)
該指令沒有的顯式操作數(shù),主要起延遲下一條指令的執(zhí)行。通常用執(zhí)行指令“XCHG AX, AX”來代表它的執(zhí)行。NOP指令的執(zhí)行不影響任何標志位。
指令的格式:NOP
2、等待指令WAIT(Put Processor in Wait State Instruction)
該指令使CPU處于等待狀態(tài),直到協(xié)處理器(Coprocessor)完成運算,并用一個重啟信號喚醒CPU為止。該指令的執(zhí)行不影響任何標志位。
指令的格式:WAIT
3、暫停指令HLT(Enter Halt State Instruction)
在等待中斷信號時,該指令使CPU處于暫停工作狀態(tài),CS:IP指向下一條待執(zhí)行的指令。當產(chǎn)生了中斷信號,CPU把CS和IP壓棧,并轉(zhuǎn)入中斷處理程序。在中斷處理程序執(zhí)行完后,中斷返回指令IRET彈出IP和CS,并喚醒CPU執(zhí)行下條指令。
指令的格式:HLT
指令的執(zhí)行不影響任何標志位。
4、封鎖數(shù)據(jù)指令LOCK(Lock Bus Instruction)
該指令是一個前綴指令形式,在其后面跟一個具體的操作指令。LOCK指令可以保證是在其后指令執(zhí)行過程中,禁止協(xié)處理器修改數(shù)據(jù)總線上的數(shù)據(jù),起到獨占總線的作用。該指令的執(zhí)行不影響任何標志位。
指令的格式:LOCK INSTRUCTION
5.3 習題
5.1、書寫正確的MOV指令,需要符合哪些規(guī)定?在32位CPU中,增加了什么指令來克服不同數(shù)據(jù)類型之間的數(shù)據(jù)傳送?
5.2、簡述指令MOV BX, 1234H、MOV BX, [1234]和MOV BX, offset [1234H]的功能和它們之間區(qū)別。
5.3、簡述指令MOV BX, Data和MOV BX, offset Data之間的區(qū)別。
5.4、選擇指令實現(xiàn)下列要求,OPN1 ← OPN2的含義:把操作數(shù)OPN2的值傳送給OPN1。
1)、EBX ← EDX
3)、SI ← BX
5)、AL ← BH
7)、AX ← 13AH
9)、SI ← 1000H
2)、BX ← CL
4)、DS ← AX
6)、AL ← 12H
8)、CX ← 0CDH (假設0CDH為無符號數(shù))
10)、EBX ← 1200A2H
5.5、PUSHA指令能把哪些寄存器壓棧?它們進棧的順序是什么?可用什么指令把這些寄存器依次彈出堆棧?
5.7、PUSHAD指令完成什么操作?它與什么操作的作用相反?
5.8、在16位/32位CPU中,標志位寄存器的內(nèi)容進棧和出棧的指令是什么?
5.9、寫出下列指令序列中每條指令的執(zhí)行結(jié)果,請在Debug環(huán)境下驗證之,并注意各標志位的變化情況。
MOV BX, 23ABH
ADD BL, 0ACH
MOV AX, 23F5H
ADD BH, AL
SBB BX, AX
ADC AX, 12H
SUB BH, -9
5.10、假定DS=1123H,SS=1400H,BX=0200H,BP=1050H,DI=0400H,SI=0500H,LIST的偏移量為250H,試確定下面各指令訪問內(nèi)存單元的地址。
1)、MOV AL, [1234H] 2)、MOV AX, [BX]
3)、MOV [DI], AL 4)、MOV [2000H], AL
5)、MOV AL, [BP+DI] 6)、MOV CX, [DI]
7)、MOV EDX, [BP] 8)、MOV LIST[SI], EDX
9
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -