学 Win32 汇编[29] - 串指令: MOVS*、CMPS*、SCAS*、LODS*、REP、REPE、REPNE 等
16lz
2021-04-30
学 Win32 汇编[29] - 串指令: MOVS*、CMPS*、SCAS*、LODS*、REP、REPE、REPNE 等
这里的 "串" 并不单指字符串, 包括所有连续的数据(如数组); 串指令只用于内存操作.
移动串指令: MOVSB、MOVSW、MOVSD ;从 ESI -> EDI; 执行后, ESI 与 EDI 的地址移动相应的单位比较串指令: CMPSB、CMPSW、CMPSD ;比较 ESI、EDI; 执行后, ESI 与 EDI 的地址移动相应的单位扫描串指令: SCASB、SCASW、SCASD ;依据 AL/AX/EAX 中的数据扫描 EDI 指向的数据, 执行后 EDI 自动变化储存串指令: STOSB、STOSW、STOSD ;将 AL/AX/EAX 中的数据储存到 EDI 给出的地址, 执行后 EDI 自动变化载入串指令: LODSB、LODSW、LODSD ;将 ESI 指向的数据载入到 AL/AX/EAX, 执行后 ESI 自动变化其中的 B、W、D 分别指 Byte、Word、DWord, 表示每次操作的数据的大小单位.上述指令可以有重复前缀:REP ECX > 0 时REPE (或 REPZ) ECX > 0 且 ZF=1 时REPNE(或 REPNZ) ECX > 0 且 ZF=0 时;重复前缀可以自动按单位(1、2、4)递减 ECX
MOVSB: 移动字符串
; Test29_1.asm.386.model flat, stdcallinclude windows.incinclude kernel32.incinclude masm32.incinclude debug.incincludelib kernel32.libincludelib masm32.libincludelib debug.lib.data szSource db 'Delphi 2010', 0 len equ $ - szSource - 1 szDest db len dup(?), 0.codemain proc lea esi, szSource lea edi, szDest mov ecx, len cld ;复位标志寄存器的方向标志, 以让串地址由低到高 rep movsb PrintString szDest ;Delphi 2010 retmain endpend main
上面的例子, 假如不使用重复前缀...
; Test29_2.asm.386.model flat, stdcallinclude windows.incinclude kernel32.incinclude masm32.incinclude debug.incincludelib kernel32.libincludelib masm32.libincludelib debug.lib.data szSource db 'Delphi 2010', 0 len equ $ - szSource - 1 szDest db len dup(?), 0.codemain proc lea esi, szSource lea edi, szDest mov ecx, len cld@@: movsb dec ecx jnz @B PrintString szDest retmain endpend main
MOVSD 例:
; Test29_3.asm.386.model flat, stdcallinclude windows.incinclude kernel32.incinclude masm32.incinclude debug.incincludelib kernel32.libincludelib masm32.libincludelib debug.lib.data ddSource dd 11h,22h,33h ddDest dd lengthof ddSource dup(?).codemain proc lea esi, ddSource lea edi, ddDest mov ecx, lengthof ddSource cld rep movsd DumpMem offset ddDest, sizeof ddDest ;11 00 00 00 - 22 00 00 00 - 33 00 00 00 retmain endpend main
MOVSW 例:
; Test29_4.asm.386.model flat, stdcallinclude windows.incinclude kernel32.incinclude masm32.incinclude debug.incincludelib kernel32.libincludelib masm32.libincludelib debug.lib.data ddSource dw 11h,22h,33h ddDest dw lengthof ddSource dup(?).codemain proc lea esi, ddSource lea edi, ddDest mov ecx, lengthof ddSource cld rep movsw DumpMem offset ddDest, sizeof ddDest ;11 00 22 00 - 33 00 00 00 retmain endpend main
CMPSD 例:
; Test29_5.asm.386p.model flat, stdcallinclude windows.incinclude kernel32.incinclude masm32.incinclude debug.incincludelib kernel32.libincludelib masm32.libincludelib debug.lib.data ddVal1 dd 1234h ddVal2 dd 5678h.codemain proc lea esi, ddVal1 lea edi, ddVal2 cmpsd je L1 PrintText '两数不等' jmp L2L1: PrintText '两数相等'L2: retmain endpend main
CMPSW 例:
; Test29_6.asm.386p.model flat, stdcallinclude windows.incinclude kernel32.incinclude masm32.incinclude debug.incincludelib kernel32.libincludelib masm32.libincludelib debug.lib.data dwArr1 dw 1,2,3,4,5 dwArr2 dw 1,3,5,7,9.codemain proc lea esi, dwArr1 lea edi, dwArr2 mov ecx, lengthof dwArr1 cld repe cmpsw je L1 PrintText '两数组不等' jmp L2L1: PrintText '两数组相等'L2: retmain endpend main
对比数组时, 假如数组长度不一致...
; Test29_7.asm.386p.model flat, stdcallinclude windows.incinclude kernel32.incinclude masm32.incinclude debug.incincludelib kernel32.libincludelib masm32.libincludelib debug.lib.data dwArr1 dw 1,2,3,4,5 dwArr2 dw 1,2,3,4,5,6.codemain proc lea esi, dwArr1 lea edi, dwArr2 mov ecx, lengthof dwArr1 cmp ecx, lengthof dwArr2 jne L1 cld repe cmpsw jne L1 PrintText '两数组相等' jmp L2L1: PrintText '两数组不等'L2: retmain endpend main
如果对比的是 0 结束的字符串, 长度不一致也不用考虑
; Test29_8.asm.386p.model flat, stdcallinclude windows.incinclude kernel32.incinclude masm32.incinclude debug.incincludelib kernel32.libincludelib masm32.libincludelib debug.lib.data szText1 db 'Delphi 2010', 0 szText2 db 'Delphi 2011', 0.codemain proc lea esi, szText1 lea edi, szText2 mov ecx, lengthof szText1 cld repe cmpsb je L1 PrintText '字符串不同' jmp L2L1: PrintText '字符串相同'L2: retmain endpend main
SCASB 例:
; Test29_9.asm.386p.model flat, stdcallinclude windows.incinclude kernel32.incinclude masm32.incinclude debug.incincludelib kernel32.libincludelib masm32.libincludelib debug.lib.data szText db 'ABCDEFGH', 0.codemain proc lea edi, szText mov al, 'F' mov ecx, lengthof szText - 1 cld repne scasb je L1 PrintText '没找到' jmp L2L1: sub ecx, lengthof szText - 1 neg ecx PrintDec ecx ;如果找得到, 这里显示是第几个字符; 本例结果是 6L2: retmain endpend main
STOSB 例:
; Test29_10.asm.386p.model flat, stdcallinclude windows.incinclude kernel32.incinclude masm32.incinclude debug.incincludelib kernel32.libincludelib masm32.libincludelib debug.lib.data len = 31 szText db len dup(0), 0.codemain proc lea edi, szText mov al, 'x' mov ecx, len cld rep stosb PrintString szText ;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx retmain endpend main
LODSW 例: 数组求和
; Test29_11.asm.386p.model flat, stdcallinclude windows.incinclude kernel32.incinclude masm32.incinclude debug.incincludelib kernel32.libincludelib masm32.libincludelib debug.lib.data dwArr dw 1,2,3,4,5,6,7,8,9,10.codemain proc lea esi, dwArr mov ecx, lengthof dwArr xor edx, edx xor eax, eax@@: lodsw add edx, eax loop @B PrintDec edx ;55 retmain endpend main
posted on 2010-04-17 22:55 万一 阅读(6141) 评论(0) 编辑 收藏©著作权归作者所有:来自51CTO博客作者JLee79的原创作品,如需转载,请注明出处,否则将追究法律责任
更多相关文章
- 学 Win32 汇编[23] - 位测试与位扫描指令: BT、BTC、BTR、BTS、B
- 学 Win32 汇编[22] - 逻辑运算指令: AND、OR、XOR、NOT、TEST
- 学 Win32 汇编[21] - 传送指令: MOV、LEA、XCHG、XLATB、XLAT、M
- 学 Win32 汇编[20]: 洞察标志寄存器
- 学 Win32 汇编[27] - 乘除指令: MUL、IMUL、DIV、IDIV
- 学用 ASP.Net 之 "字符串" (3): string 类的非扩展方法
- 学 Win32 汇编[26] - 加减指令: INC、DEC、NEG、ADD、ADC、SUB、
- 学 Win32 汇编[25] - 符号扩展指令: CBW、CWDE、CDQ、CWD
- 学 Win32 汇编[15]: LOOP 与标号