本文主要是介绍学 Win32 汇编[29] - 串指令: MOVS*、CMPS*、SCAS*、LODS*、REP、REPE、REPNE 等,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
学 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, stdcall
include windows.inc
include kernel32.inc
include masm32.inc
include debug.inc
includelib kernel32.lib
includelib masm32.lib
includelib debug.lib
.data
szSource db 'Delphi 2010', 0
len equ $ - szSource - 1
szDest db len dup(?), 0
.code
main proc
lea esi, szSource
lea edi, szDest
mov ecx, len
cld ;复位标志寄存器的方向标志, 以让串地址由低到高
rep movsb
PrintString szDest ;Delphi 2010
ret
main endp
end main
上面的例子, 假如不使用重复前缀...
; Test29_2.asm
.386
.model flat, stdcall
include windows.inc
include kernel32.inc
include masm32.inc
include debug.inc
includelib kernel32.lib
includelib masm32.lib
includelib debug.lib
.data
szSource db 'Delphi 2010', 0
len equ $ - szSource - 1
szDest db len dup(?), 0
.code
main proc
lea esi, szSource
lea edi, szDest
mov ecx, len
cld
@@: movsb
dec ecx
jnz @B
PrintString szDest
ret
main endp
end main
MOVSD 例:
; Test29_3.asm
.386
.model flat, stdcall
include windows.inc
include kernel32.inc
include masm32.inc
include debug.inc
includelib kernel32.lib
includelib masm32.lib
includelib debug.lib
.data
ddSource dd 11h,22h,33h
ddDest dd lengthof ddSource dup(?)
.code
main 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
ret
main endp
end main
MOVSW 例:
; Test29_4.asm
.386
.model flat, stdcall
include windows.inc
include kernel32.inc
include masm32.inc
include debug.inc
includelib kernel32.lib
includelib masm32.lib
includelib debug.lib
.data
ddSource dw 11h,22h,33h
ddDest dw lengthof ddSource dup(?)
.code
main 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
ret
main endp
end main
CMPSD 例:
; Test29_5.asm
.386p
.model flat, stdcall
include windows.inc
include kernel32.inc
include masm32.inc
include debug.inc
includelib kernel32.lib
includelib masm32.lib
includelib debug.lib
.data
ddVal1 dd 1234h
ddVal2 dd 5678h
.code
main proc
lea esi, ddVal1
lea edi, ddVal2
cmpsd
je L1
PrintText '两数不等'
jmp L2
L1: PrintText '两数相等'
L2: ret
main endp
end main
CMPSW 例:
; Test29_6.asm
.386p
.model flat, stdcall
include windows.inc
include kernel32.inc
include masm32.inc
include debug.inc
includelib kernel32.lib
includelib masm32.lib
includelib debug.lib
.data
dwArr1 dw 1,2,3,4,5
dwArr2 dw 1,3,5,7,9
.code
main proc
lea esi, dwArr1
lea edi, dwArr2
mov ecx, lengthof dwArr1
cld
repe cmpsw
je L1
PrintText '两数组不等'
jmp L2
L1: PrintText '两数组相等'
L2: ret
main endp
end main
对比数组时, 假如数组长度不一致...
; Test29_7.asm
.386p
.model flat, stdcall
include windows.inc
include kernel32.inc
include masm32.inc
include debug.inc
includelib kernel32.lib
includelib masm32.lib
includelib debug.lib
.data
dwArr1 dw 1,2,3,4,5
dwArr2 dw 1,2,3,4,5,6
.code
main proc
lea esi, dwArr1
lea edi, dwArr2
mov ecx, lengthof dwArr1
cmp ecx, lengthof dwArr2
jne L1
cld
repe cmpsw
jne L1
PrintText '两数组相等'
jmp L2
L1: PrintText '两数组不等'
L2: ret
main endp
end main
如果对比的是 0 结束的字符串, 长度不一致也不用考虑
; Test29_8.asm
.386p
.model flat, stdcall
include windows.inc
include kernel32.inc
include masm32.inc
include debug.inc
includelib kernel32.lib
includelib masm32.lib
includelib debug.lib
.data
szText1 db 'Delphi 2010', 0
szText2 db 'Delphi 2011', 0
.code
main proc
lea esi, szText1
lea edi, szText2
mov ecx, lengthof szText1
cld
repe cmpsb
je L1
PrintText '字符串不同'
jmp L2
L1: PrintText '字符串相同'
L2: ret
main endp
end main
SCASB 例:
; Test29_9.asm
.386p
.model flat, stdcall
include windows.inc
include kernel32.inc
include masm32.inc
include debug.inc
includelib kernel32.lib
includelib masm32.lib
includelib debug.lib
.data
szText db 'ABCDEFGH', 0
.code
main proc
lea edi, szText
mov al, 'F'
mov ecx, lengthof szText - 1
cld
repne scasb
je L1
PrintText '没找到'
jmp L2
L1: sub ecx, lengthof szText - 1
neg ecx
PrintDec ecx ;如果找得到, 这里显示是第几个字符; 本例结果是 6
L2: ret
main endp
end main
STOSB 例:
; Test29_10.asm
.386p
.model flat, stdcall
include windows.inc
include kernel32.inc
include masm32.inc
include debug.inc
includelib kernel32.lib
includelib masm32.lib
includelib debug.lib
.data
len = 31
szText db len dup(0), 0
.code
main proc
lea edi, szText
mov al, 'x'
mov ecx, len
cld
rep stosb
PrintString szText ;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
ret
main endp
end main
LODSW 例: 数组求和
; Test29_11.asm
.386p
.model flat, stdcall
include windows.inc
include kernel32.inc
include masm32.inc
include debug.inc
includelib kernel32.lib
includelib masm32.lib
includelib debug.lib
.data
dwArr dw 1,2,3,4,5,6,7,8,9,10
.code
main proc
lea esi, dwArr
mov ecx, lengthof dwArr
xor edx, edx
xor eax, eax
@@: lodsw
add edx, eax
loop @B
PrintDec edx ;55
ret
main endp
end main
posted on
2010-04-17 22:55
万一
阅读(6141)
评论(0)
编辑
收藏
这篇关于学 Win32 汇编[29] - 串指令: MOVS*、CMPS*、SCAS*、LODS*、REP、REPE、REPNE 等的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!