我想知道设置或清除方向 EFLAG 如何改变 SCAS 和 MOV 指令如何递减或递增寄存器。我阅读了一些网页并做出了以下假设,我将在下面列出。
我正在使用 MASM 32 SDK - 不知道是什么版本,我通过 Visual MASM 的下载和安装向导安装了 - 使用 Visual MASM 和 MASM32 编辑器将它们链接并构建到对象和可执行文件中。我使用的是 Windows 7 Pro 64 位操作系统。
SCAS
SCAS 指令“将 AL 中的字节或 AX 中的字与 ES 中的 DI 指向的字节或字进行比较”。因此,要使用 SCAS,必须将目标字符串地址移动到 EDI,并且必须将要查找的字符串移动到累加器寄存器(EAX 和变体)。
在使用 32 位系统时,设置方向标志然后使用 SCAS 将停止 SCAS 运行。在 32 位系统上,不可能强制 SCAS“从头到尾扫描字符串”。
任何 REP 指令始终使用 ECX 寄存器作为计数器,并且始终递减 ECX,而不管方向标志的值如何。这意味着使用 REP SCAS 不可能“从头到尾扫描字符串”。
资料来源:
SCAS/SCASB/SCASW,Birla Institute of Technology and Science
扫描字符串,来自 c9xm.me
SCAS/SCASB/SCASW/SCASD — 扫描字符串,来自 felixcloutier.com
MASM:使用“字符串”说明,来自 www.dreamincode.net /论坛
以下是我将在问题中引用的程序的部分代码:
;Generic settings from MASM32 editor
.386
.model flat, stdcall
option casemap: none
.data?
Input db 254 dup(?)
InputCopy db 254 dup(?)
InputLength dd ?, 0
InputEnd dd ?, 0
.data
.code
start:
push 254
push offset Input
call StdIn
mov InputLength, eax
;---Move Last Word---
lea esi, offset Input
sub esi, 4
lea edi, offset InputEnd
movw
;---Search section---
lea esi, Input
lea edi, InputCopy
movsb
mov ecx, InputLength
mov eax, 0
mov eax, "omit"
lea edi, offset InputEnd
repne scasw
jz close ;jump if a match was found and ZF was set to 1.
- “搜索”部分下的代码一次搜索字符串 InputEnd 4 个字节,因此一次搜索 4 个字符。该块扫描EAX中的字符,即单词“省略”,总是从edi中的内存地址的值开始,然后根据SCAS的后缀(B,W,D,Q)递增(MASM:使用'String ' 说明,dream-in-code.com)。
MOVS
使用“移动最后一个单词”部分,我可以从字符串 Input 中获取最后一个字节。然后我使用 MOVSW 将字符串 Input 的最后 4 个字节移动到 InputEnd,假设方向标志是明确的。我必须将 Input 定义为一个字节数组
Input db 32 dup(?)
- 才能使块工作。无论我如何定义 InputEnd(无论是“dd ?, 0”还是“db 12 dup(?)”),mov 和 scas 指令的操作(标志设置、寄存器修改等)都不会改变。SCAS 和 MOV 的递增/递减量取决于命令的后缀/最后一个字母,而不是存储在 EDI 和 ESI 中的指针的定义字节或大小。
使MOVS从字符串的开头转移到结尾是不可能的。你必须是字符串的长度;将对应的地址加载到EDI和ESI;将字符串的长度添加到存储在 EDI 和 ESI 的地址中;最后,使用 设置方向标志
std
。这里的一个危险是目标地址低于源或目标字节。使用 MOVS 反转字符串的字母是不可能的,因为 EDI 和 ESI 要么都被 MOVS 递减,要么都被递增。
来源(除了之前在 SCAS 部分中列出的站点):
https://c9x.me/x86/html/file_module_x86_id_203.html
http://faydoc.tripod.com/cpu/movsd.htm
这些假设是否正确?网站 URL 上的 x86 文本是否表明网站信息错误?