分享

学 Win32 汇编[29]

 欣然看花 2017-12-09
这里的 "串" 并不单指字符串, 包括所有连续的数据(如数组); 串指令只用于内存操作.
移动串指令: MOVSBMOVSWMOVSD ;从 ESI -> EDI; 执行后, ESI 与 EDI 的地址移动相应的单位
比较串指令: CMPSBCMPSWCMPSD ;比较 ESI、EDI; 执行后, ESI 与 EDI 的地址移动相应的单位
扫描串指令: SCASBSCASWSCASD ;依据 AL/AX/EAX 中的数据扫描 EDI 指向的数据, 执行后 EDI 自动变化
储存串指令: STOSBSTOSWSTOSD ;将 AL/AX/EAX 中的数据储存到 EDI 给出的地址, 执行后 EDI 自动变化
载入串指令: LODSBLODSWLODSD ;将 ESI 指向的数据载入到 AL/AX/EAX, 执行后 ESI 自动变化

其中的 B、W、D 分别指 ByteWordDWord, 表示每次操作的数据的大小单位.

上述指令可以有重复前缀:
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

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多