发布于 ,更新于 

x86 串操作指令

方向标志位 DF

方向标志位 DFEFLAGS 寄存器中的 bit-10,用于指明串操作的方向。

  • SI/ESI/RSI 寄存器中的 S 代表 “源” (只配合 DS 段使用)
  • DI/EDI/RDI 寄存器中的 D 代表 “目标”(只配合 ES 段使用)
  1. DF 为 0 时,每次操作之后,SI/ESI/RSI、DI/EDI/RDI 寄存器递增
  2. DF 为 0 时,每次操作之后,SI/ESI/RSI、DI/EDI/RDI 寄存器递减

  • CLD 指令: 该指令将 DF 清 0
  • STD 指令: 该指令将 DF 置 1

串传送指令

1. MOVSB

  • 将 SI/ESI/RSI 指定的源内存地址中 1 个字节的数据,传送到 DI/EDI/RDI 指定的目标内存地址中。
  • 并且,SI/ESI/RSI 和 DI/EDI/RDI 根据 DF 标志自动递增或者递减 1。

2. MOVSW

  • 将 SI/ESI/RSI 指定的源内存地址中 2 个字节的数据,传送到 DI/EDI/RDI 指定的目标内存地址中。
  • 并且,SI/ESI/RSI 和 DI/EDI/RDI 根据 DF 标志自动递增或者递减 2。

3. MOVSL (AT&T语法) MOVSD (Intel语法)

  • 将 SI/ESI/RSI 指定的源内存地址中 4 个字节的数据,传送到 DI/EDI/RDI 指定的目标内存地址中。
  • 并且,SI/ESI/RSI 和 DI/EDI/RDI 根据 DF 标志自动递增或者递减 4。

4. MOVSQ

  • 将 SI/ESI/RSI 指定的源内存地址中 8 个字节的数据,传送到 DI/EDI/RDI 指定的目标内存地址中。
  • 并且,SI/ESI/RSI 和 DI/EDI/RDI 根据 DF 标志自动递增或者递减 8。

REP 前缀

串操作指令一般是配合 rep 前缀使用。 rep 前缀的作用是根据 CX/ECX/RCX 寄存器的值,重复执行多次串指令,每执行一次, CX/ECX/RCX 自动减 1。

1
rep  movsw

相当于如下指令:

1
2
3
L1:
movsw
loop L1

串加载指令

1. LODSB

  • 将 SI/ESI/RSI 指定的源内存地址中 1 个字节的数据,传送到 AL 寄存器中。
  • 并且,SI/ESI/RSI 根据 DF 标志自动递增或者递减 1。

2. LODSW

  • 将 SI/ESI/RSI 指定的源内存地址中 2 个字节的数据,传送到 AX 寄存器中。
  • 并且,SI/ESI/RSI 根据 DF 标志自动递增或者递减 2。

3. LODSL (AT&T语法) LODSD (Intel语法)

  • 将 SI/ESI/RSI 指定的源内存地址中 4 个字节的数据,传送到 EAX 寄存器中。
  • 并且,SI/ESI/RSI 根据 DF 标志自动递增或者递减 4。

4. LODSQ

  • 将 SI/ESI/RSI 指定的源内存地址中 8 个字节的数据,传送到 RAX 寄存器中。
  • 并且,SI/ESI/RSI 根据 DF 标志自动递增或者递减 8。

串存储指令

1. STOSB

  • 将 AL 寄存器的值(1 个字节)存储到 DI/EDI/RDI 指定的目标内存地址中。
  • 并且,DI/EDI/RDI 根据 DF 标志自动递增或者递减 1。

2. STOSW

  • 将 AX 寄存器的值(2 个字节)存储到 DI/EDI/RDI 指定的目标内存地址中。
  • 并且,DI/EDI/RDI 根据 DF 标志自动递增或者递减 2。

3. STOSL (AT&T语法) STOSD (Intel语法)

  • 将 EAX 寄存器的值(4 个字节)存储到 DI/EDI/RDI 指定的目标内存地址中。
  • 并且,DI/EDI/RDI 根据 DF 标志自动递增或者递减 4。

4. STOSQ

  • 将 RAX 寄存器的值(8 个字节)存储到 DI/EDI/RDI 指定的目标内存地址中。
  • 并且,DI/EDI/RDI 根据 DF 标志自动递增或者递减 8。

STOSB/STOSW/STOSL/STOSQ 可以配合 rep 前缀对大内存缓冲区进行初始化。

串比较指令

1. CMPSB

  • SI/ESI/RSI 指定的源内存地址,DI/EDI/RDI 指定的目标内存,1 字节减操作,源减去目标,然后根据结果设置 EFLAGS 寄存器标志。
  • 并且,SI/ESI/RSI 和 DI/EDI/RDI 根据 DF 标志自动递增或者递减 1。

2. CMPSW

  • SI/ESI/RSI 指定的源内存地址,DI/EDI/RDI 指定的目标内存,2 字节减操作,源减去目标,然后根据结果设置 EFLAGS 寄存器标志。
  • 并且,SI/ESI/RSI 和 DI/EDI/RDI 根据 DF 标志自动递增或者递减 2。

3. CMPSL (AT&T语法) CMPSD (Intel语法)

  • SI/ESI/RSI 指定的源内存地址,DI/EDI/RDI 指定的目标内存,4 字节减操作,源减去目标,然后根据结果设置 EFLAGS 寄存器标志。
  • 并且,SI/ESI/RSI 和 DI/EDI/RDI 根据 DF 标志自动递增或者递减 4。

4. CMPSQ

  • SI/ESI/RSI 指定的源内存地址,DI/EDI/RDI 指定的目标内存,8 字节减操作,源减去目标,然后根据结果设置 EFLAGS 寄存器标志。
  • 并且,SI/ESI/RSI 和 DI/EDI/RDI 根据 DF 标志自动递增或者递减 8。

CMPSB/CMPSW/CMPSL/CMPSQ 可以配合 REP、REPE、REPNE、REPZ、REPNZ前缀一起使用来实现各种字符串比较操作。

串扫描指令

1. SCASB

  • AL 作为源操作数,DI/EDI/RDI 指定的目标内存,1 字节减操作,源减去目标,然后根据结果设置 EFLAGS 寄存器标志。
  • 并且,DI/EDI/RDI 根据 DF 标志自动递增或者递减 1。

2. SCASW

  • AX 作为源操作数,DI/EDI/RDI 指定的目标内存,2 字节减操作,源减去目标,然后根据结果设置 EFLAGS 寄存器标志。
  • 并且,DI/EDI/RDI 根据 DF 标志自动递增或者递减 1。

3. SCASL (AT&T语法) SCASD (Intel语法)

  • EAX 作为源操作数,DI/EDI/RDI 指定的目标内存,4 字节减操作,源减去目标,然后根据结果设置 EFLAGS 寄存器标志。
  • 并且,DI/EDI/RDI 根据 DF 标志自动递增或者递减 1。

4. SCASQ

  • RAX 作为源操作数,DI/EDI/RDI 指定的目标内存,8 字节减操作,源减去目标,然后根据结果设置 EFLAGS 寄存器标志。
  • 并且,DI/EDI/RDI 根据 DF 标志自动递增或者递减 1。

SCASB/SCASW/SCASL/SCASQ 可以配合 REP、REPE、REPNE、REPZ、REPNZ前缀一起使用来实现各种字符串比较、查找操作。









汇编语言程序设计