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遞減到零。