彙編 - 字串



我們已經在之前的示例中使用了變長字串。變長字串可以包含任意數量的字元。通常,我們透過以下兩種方式之一指定字串的長度:

  • 顯式儲存字串長度
  • 使用哨兵字元

我們可以使用表示當前位置計數器值的 $ 位置計數器符號顯式儲存字串長度。在下面的示例中:

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

字串指令

每個字串指令可能需要一個源運算元、一個目標運算元或兩者兼而有之。對於 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 位地址,使用 SI 和 DI 暫存器,對於 32 位地址,使用 ESI 和 EDI 暫存器。

下表提供了字串指令的各種版本以及運算元的假設空間。

基本指令 運算元位於 位元組操作 字操作 雙字操作
MOVS ES:DI, DS:SI 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 執行指令,將 CX 減 1,並檢查 CX 是否為零。它重複指令處理,直到 CX 為零。

方向標誌 (DF) 確定操作的方向。

  • 使用 CLD(清除方向標誌,DF = 0)使操作從左到右。
  • 使用 STD(設定方向標誌,DF = 1)使操作從右到左。

REP 字首還有以下變體

  • REP:它是無條件重複。它重複操作直到 CX 為零。

  • REPE 或 REPZ:它是條件重複。它在零標誌指示相等/零時重複操作。當 ZF 指示不相等/零或 CX 為零時停止。

  • REPNE 或 REPNZ:它也是條件重複。它在零標誌指示不相等/零時重複操作。當 ZF 指示相等/零或 CX 減至零時停止。

廣告

© . All rights reserved.