Assembly彙編 字符串處理

在我們前面的例子中,我們已經使用可變長度的字符串。注意到可變長度的字符串可以有儘可能多的字符。一般情況下,我們指定的字符串長度的兩種方法之一:

  • 明確存儲字符串長度

  • 使用定點字符

我們可以明確存儲字符串的長度,使用位置計數器符號代表位置計數器的當前值。在下面的例子:

msg db 'Hello, world!',0xa ;our dear string len equ $ - msg ;length of our dear string

$ 點後的字節的最後一個字符的字符串變量msg。因此,**$-msg** 給出的字符串的長度。我們也可以寫:

msg db 'Hello, world!',0xa ;our dear string len equ 13 ;length of our dear string

或者可以存儲結尾的定點字符分隔的字符串,而不是顯式存儲的字符串長度的字符串。定點字符應該是一個不會出現在字符串中的特殊字符。

例子:

message DB 'I am loving it!', 0

String指令

每個字符串指令可能需要一個源操作數,目的操作數或兩者兼有。對於32位段,串指令使用ESI和EDI寄存器分別指向源和目的操作數。

然而對於16位段,SI和DI寄存器用於分別爲指向的源和目標。

有五種基本指令處理字符串。它們分別是:

  • MOVS - 該指令移動1字節,字或雙字的數據從內存中的位置到另一個。

  • LODS - 該指令從存儲器加載。如果操作數是一個字節,它被加載到AL寄存器中,如果操作數是一個字,它被裝入AX寄存器EAX寄存器被裝入一個雙字。

  • STOS - 該指令寄存器(AL,AX或EAX)內存存儲數據。

  • CMPS - 這個指令比較兩個數據項在內存中。數據可能是一個字節大小,字或雙字。

  • SCAS - 該指令寄存器(AL,AX或EAX)的內容進行比較,在內存中的一個項目的內容。

上述指令的字節,字和雙版本,並可以重複使用重複前綴字符串指令。

這些指令使用ES:DI和DS:SI對寄存器DI和SI寄存器包含有效的偏移地址,是指存儲在內存中的字節。 SI通常與DS(數據段)和DI總是與ES(附加段)。

DS:SI(或ESI)和ES:DI(或EDI)的源和目的操作數寄存器指向。源操作數被假設爲在DS:SI(或ESI)和目標操作數ES:DI(或EDI)在內存中。

對於16-bit地址SI和DI寄存器的使用和使用ESI和EDI寄存器用於32位地址。

下表提供了各種版本的字符串指令和操作數的假設空間。

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寄存器下計數器的指令的基礎上重複。 REP執行的指令,減小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遞減到零。