x86 串操作指令
方向标志位 DF
方向标志位 DF
是 EFLAGS
寄存器中的 bit-10,用于指明串操作的方向。
SI/ESI/RSI
寄存器中的 S 代表 “源” (只配合 DS 段使用)DI/EDI/RDI
寄存器中的 D 代表 “目标”(只配合 ES 段使用)
- DF 为 0 时,每次操作之后,SI/ESI/RSI、DI/EDI/RDI 寄存器递增
- DF 为 0 时,每次操作之后,SI/ESI/RSI、DI/EDI/RDI 寄存器递减
CLD
指令: 该指令将 DF 清 0STD
指令: 该指令将 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 | 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前缀一起使用来实现各种字符串比较、查找操作。