(11)字符串操做指令指針
字符串操做指令的實質是對一片連續存儲單元進行處理,這片存儲單元是由隱含指針DS:SI或ES:DI來指定的。字符串操做指令可對內存單元按字節、字或雙字進行處理,並能根據操做對象的字節數使變址寄存器SI(和DI)增減一、2或4。具體規定以下:對象
(1)、當DF=0時,變址寄存器SI(和DI)增長一、2或4;blog
(2)、當DF=1時,變址寄存器SI(和DI)減小一、2或4。ip
在後面各指令中,有關變址寄存器都按上述規定進行增減,再也不一一說明。內存
1、取字符串數據指令(Load String Instruction)字符串
從由指針DS:SI所指向的內存單元開始,取一個字節、字或雙字進入AL、AX或EAX中,並根據標誌位DF對寄存器SI做相應增減。該指令的執行不影響任何標誌位。get
指令的格式:LODS 地址表達式it
LODSB/LODSWio
LODSD ;80386+變量
在指令LODS中,它會根據其地址表達式的屬性來決定讀取一個字節、字或雙字。即:當該地址表達式的屬性爲字節、字或雙字時,將從指針DS:SI處讀一個字節到AL中,或讀一個字到AX,或讀一個雙字到EAX中,與此同時,SI還將分別增減1,2或4。
其它字符串指令中的「地址表達式」做用與此相似,將再也不說明。
2、置字符串數據指令(Store String Instruction)
該指令是把寄存器AL、AX或EAX中的值存於以指針ES:DI所指向內存單元爲起始的一片存儲單元裏,並根據標誌位DF對寄存器DI做相應增減。該指令不影響任何標誌位。
指令的格式:STOS 地址表達式
STOSB/STOSW
STOSD ;80386+
3、字符串傳送指令(Move String Instruction)
該指令是把指針DS:SI所指向的字節、字或雙字傳送給指針ES:DI所指向內存單元,並根據標誌位DF對寄存器DI和SI做相應增減。該指令的執行不影響任何標誌位。
指令的格式:MOVS 地址表達式1, 地址表達式2
MOVSB/MOVSW
MOVSD ;80386+
4、輸入字符串指令(Input String Instruction)
該指令是從某一指定的端口接受一個字符串,並存入一片存儲單元之中。輸入端口由DX指定,存儲單元的首地址和讀入數據的個數分別由ES:DI和CX來肯定。在指令的執行過程當中,還根據標誌位DF對寄存器DI做相應增減。該指令不影響任何標誌位。
與指令有關的操做數ES、DI、DX和CX等都是隱含操做數。
指令的格式:INS 地址表達式
INSB/INSW
INSD ;80286+
5、輸出字符串指令(Output String Instruction)
該指令是把一個字符串輸入到指定的輸出端口中。輸出端口由DX指定,其輸出數據的首地址和個數分別由DS:SI和CX來肯定。在指令的執行過程當中,還根據標誌位DF對寄存器SI做相應增減。該指令的執行不影響任何標誌位。
與指令有關的操做數DS、SI、DX和CX等都是隱含操做數。
指令的格式:OUTS 地址表達式
OUTSB/OUTSW
OUTSD ;80286+
6、字符串比較指令(Compare String Instruction)
該指令是把指針DS:SI和ES:DI所指向字節、字或雙字的值相減,並用所獲得的差來設置有關的標誌位。與此同時,變址寄存器SI和DI也將根據標誌位DF的值做相應增減。
指令的格式:CMPS 地址表達式1, 地址表達式2
CMPSB/CMPSW
CMPSD ;80386+
受影響的標誌位:AF、CF、OF、PF、SF和ZF
7、字符串掃描指令(Scan String Instruction)
該指令是用指針ES:DI所指向字節、字或雙字的值與相應的AL、AX或EAX的值相減,用所獲得的差來設置有關標誌位。與此同時,變址寄存器DI還將根據標誌位DF的值進行增減。
指令的格式:SCAS 地址表達式1
SCASB/SCASW
SCASD ;80386+
受影響的標誌位:AF、CF、OF、PF、SF和ZF
8、重複字符串操做指令(Repeat String Instruction)
前面介紹了七種不一樣的字符串操做指令:取字符串數據、置字符串數據、字符串傳送、輸入字符串、輸出字符串、字符串比較和字符串掃描等指令,所敘述是這些指令執行一次所具備的功能。但咱們知道:每一個字符串一般會有多個字符的,因此,就須要重複執行這些字符串操做指令。爲了知足這種需求,指令系統提供了一組重複前綴指令。
雖然在這些字符串指令的前面均可以添加一個重複前綴指令,但因爲指令執行結果的差別,對某個具體的字符串指令又不用重複前綴指令而改用其它循環來實現重複的須要。
重複字符串操做指令對標誌位的影響是由被重複的字符串操做指令來決定。
(a) 重複前綴指令REP(Repeat String Instruction)
重複前綴指令是重複其後的字符串操做指令,重複的次數由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
重複前綴指令的執行步驟以下:
(1)、判斷:CX=0;
(2)、若是CX=0,則結束重複操做,執行程序中的下一條指令;
(3)、不然,CX=CX-1(不影響有關標誌位),並執行其後的字符串操做指令,在該指令執行完後,再轉到步驟(1)。
從上面的重複前綴指令格式來看,雖然咱們可使用重複取字符串數據指令(第一組指令),但可能會由於指令的執行結果而在程序中幾乎不被使用。
例5.20 編寫一段程序,計算字符串「12345abcdefgh」中字符的ASCII之和。
解:
…
MESS DB '12345abcdefgh' ;在數據段中進行變量說明
…
MOV AX, SEG MESS
MOV DS, AX
LEA SI, MESS ;用DS:SI來指向字符串的首地址
MOV CX, 13D ;重複次數
XOR BX, BX ;置求和的初值爲0
REP LODSB
…
雖然指令「REP LODSB」能從字符串中取出每一個字符,但它是在一條指令中完成的,程序的其它指令根本沒法處理每次取出的數據,指令的執行結果是:AL只保存最後一次所取出的字符'h'的ASCII碼。
因此,爲了實現本例的要求,不能使用重複前綴指令,而要把指令「REP LODSB」改寫成以下四條指令:
XOR AH, AH ;爲後面的累加做準備
again: LODSB
ADD BX, AX ;AL是被取出的字符,AH已被清0
LOOP again
(b) 條件重複前綴指令REPE(Repeat String Conditionally)
條件重複前綴指令與前面的重複前綴指令功能相相似,所不一樣的是:其重複次數不只由CX來決定,並且還會由標誌位ZF來決定。根據ZF所起的做用又分爲二種:相等重複前綴指令REPE/REPZ和不等重複前綴指令REPNE/REPNZ。
A、相等重複前綴指令的通常格式爲:
REPE/REPZ SCAS/SCASB/SCASW/SCASD
REPE/REPZ CMPS/CMPSB/CMPSW/CMPSD
該重複前綴指令的執行步驟以下:
(1)、判斷條件:CX≠0 且 ZF=1;
(2)、若是條件不成立,則結束重複操做,執行程序中的下一條指令;
(3)、不然,CX=CX-1(不影響有關標誌位),並執行其後的字符串操做指令,在該指令執行完後,再轉到步驟(1)。
B、不等重複前綴指令的通常格式爲:
REPNE/REPNZ SCAS/SCASB/SCASW/SCASD
REPNE/REPNZ CMPS/CMPSB/CMPSW/CMPSD
該重複前綴指令的執行步驟以下:
(1)、判斷條件:CX≠0 且 ZF=0;
(2)、若是條件不成立,則結束重複操做,執行程序中的下一條指令;
(3)、不然,CX=CX-1(不影響有關標誌位),並執行其後的字符串操做指令,在該指令執行完後,再轉到步驟(1)。