在我們前面的例子中,我們已經(jīng)使用可變長度的字符串。注意到可變長度的字符串可以有盡可能多的字符。一般情況下,我們指定的字符串長度的兩種方法之一:
明確存儲字符串長度
使用定點字符
我們可以明確存儲字符串的長度,使用位置計數(shù)器符號代表位置計數(shù)器的當前值。在下面的例子:
msg db 'Hello, world!',0xa ;our dear string len equ $ - msg ;length of our dear string
$ 點后的字節(jié)的最后一個字符的字符串變量msg。因此,$-msg 給出的字符串的長度。我們也可以寫:
msg db 'Hello, world!',0xa ;our dear string len equ 13 ;length of our dear string
或者可以存儲結(jié)尾的定點字符分隔的字符串,而不是顯式存儲的字符串長度的字符串。定點字符應該是一個不會出現(xiàn)在字符串中的特殊字符。
例子:
message DB 'I am loving it!', 0
每個字符串指令可能需要一個源操作數(shù),目的操作數(shù)或兩者兼有。對于32位段,串指令使用ESI和EDI寄存器分別指向源和目的操作數(shù)。
然而對于16位段,SI和DI寄存器用于分別為指向的源和目標。
有五種基本指令處理字符串。它們分別是:
MOVS - 該指令移動1字節(jié),字或雙字的數(shù)據(jù)從內(nèi)存中的位置到另一個。
LODS - 該指令從存儲器加載。如果操作數(shù)是一個字節(jié),它被加載到AL寄存器中,如果操作數(shù)是一個字,它被裝入AX寄存器EAX寄存器被裝入一個雙字。
STOS - 該指令寄存器(AL,AX或EAX)內(nèi)存存儲數(shù)據(jù)。
CMPS - 這個指令比較兩個數(shù)據(jù)項在內(nèi)存中。數(shù)據(jù)可能是一個字節(jié)大小,字或雙字。
SCAS - 該指令寄存器(AL,AX或EAX)的內(nèi)容進行比較,在內(nèi)存中的一個項目的內(nèi)容。
上述指令的字節(jié),字和雙版本,并可以重復使用重復前綴字符串指令。
這些指令使用ES:DI和DS:SI對寄存器DI和SI寄存器包含有效的偏移地址,是指存儲在內(nèi)存中的字節(jié)。 SI通常與DS(數(shù)據(jù)段)和DI總是與ES(附加段)。
DS:SI(或ESI)和ES:DI(或EDI)的源和目的操作數(shù)寄存器指向。源操作數(shù)被假設為在DS:SI(或ESI)和目標操作數(shù)ES:DI(或EDI)在內(nèi)存中。
對于16-bit地址SI和DI寄存器的使用和使用ESI和EDI寄存器用于32位地址。
下表提供了各種版本的字符串指令和操作數(shù)的假設空間。
Basic Instruction | Operands at | Byte Operation | Word Operation | Double word Operation |
---|---|---|---|---|
MOVS | ES:DI, DS:EI | MOVSB | MOVSW | MOVSD |
LODS | AX, DS:SI | LODSB | LODSW | LODSD |
STOS | ES:DI, AX | STOSB | STOSW | STOSD |
CMPS | DS:SI, ES: DI | CMPSB | CMPSW | CMPSD |
SCAS | ES:DI, AX | SCASB | SCASW | SCASD |
前一個字符串的指令,例如,當設置的REP前綴 - REP MOVSB??,使在CX寄存器下計數(shù)器的指令的基礎上重復。 REP執(zhí)行的指令,減小CX1,并檢查是否CX為0。重復指令處理,,直到CX是零。
方向標志(DF)確定的方向的操作。
Use CLD (Clear Direction Flag, DF = 0)使操作左到右。
Use STD (Set Direction Flag, DF = 1) 使操作從右到左。
REP前綴也有以下的變化:
REP: 它是無條件的重復。它重復操作,直到CX是零。
REPE or REPZ: 它是有條件的重復。它重復操作,而零標志表示等于/零。它停止時,表示不等于ZF/零或當CX是零。
REPNE or REPNZ:這也是有條件的重復。重復操作,而零標志表明不等于/零。它停止時,ZF表示零或等于/ CX遞減到零。