位置:首页 > > Assembly 字符串处理

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递减到零。