I want to know how setting or clearing the direction EFLAG changes how the SCAS and MOV instructions decrement or increment registers. I read some webpages and made the following assumptions I will list below.
I am using the MASM 32 SDK - no idea what version, I installed via Visual MASM's download and installation wizard - with Visual MASM to wright and MASM32 Editor to link and build them into objects and executables. I use a Windows 7 Pro 64 bit OS.
SCAS
The SCAS instruction "compares a byte in AL or a word in AX with a byte or word pointed to by DI in ES." Therefore,to use SCAS, target string address must be moved to EDI and the string to find must be moved to the accumulator register (EAX and variants).
Setting direction flag then using SCAS will stop SCAS from running when using 32 bit systems. On 32 bit systems, it is impossible to force SCAS to "scan a string from the end to the start."
Any REP instruction always uses the ECX register as a counter and always decrements ECX regardless of the direction flag's value. This means it is impossible to "scan a string from the end to the beginning" using REP SCAS.
Sources:
SCAS/SCASB/SCASW, Birla Institute of Technology and Science
Scan String, from c9xm.me
SCAS/SCASB/SCASW/SCASD — Scan String, from felixcloutier.com
MASM : Using 'String' Instructions, from www.dreamincode.net/forums
Below is part of the code from a program I will refer to in my questions:
;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.
- The code under the "Search" section searches the string InputEnd 4 bytes at a time and thus 4 characters at a time. The block scans for the characters in EAX, i.e. the word "omit", ALWAYS beginning at the value of the memory address in edi then incrementing based on the suffix of SCAS (B, W, D, Q)(MASM : Using 'String' Instructions, dream-in-code.com).
MOVS
Using the "Move Last Word" section, I am able to get the last byte out of the string Input. I then used MOVSW to move just the last 4 bytes of the string Input to InputEnd, assuming the direction flag is clear. I must define Input as an array of bytes -
Input db 32 dup(?)
- for the block to work.Regardless of how I define InputEnd (whether "dd ?, 0" or "db 12 dup(?)") mov and scas instructions' operation (flags set, registers modified etc.) will not change. The increment/decrement amount of SCAS and MOV are dependent on the suffix/last letter of the command, not the defined bytes or size of the pointers stored in EDI and ESI.
It is impossible to make MOVS transfer from the beginning to the end of a string. You must the length of the string; load the corresponding addresses to EDI and ESI; Add the length of the string to the addresses stored at EDI and ESI; Last, set the direction flag using
std
. A danger here is targeting addresses below the source or destination bytes.It is impossible to reverse a string's letters using MOVS since EDI and ESI are either both decremented or both incremented by MOVS.
Sources (asides from previously listed sites in SCAS section):
https://c9x.me/x86/html/file_module_x86_id_203.html
http://faydoc.tripod.com/cpu/movsd.htm
Are these assumptions correct? Is the x86 text on the sites' URLs a sign that the websites have wrong information?
movs
. Actually the question already links the entry for SCAS so IDK what they're not understanding. – Mosasaurmovsw
. In 32-bit mode,movsw
requires an operand-size prefix. Just likemovsd
in 16-bit mode. So the always-1-byte table is only right if you assume that only 16-bit code usesmovsw
etc. – Mosasaur