I want to change flag UP to one, now it is UP = 0. I am using Visual Studio 64-bit assembly.
(Intel calls this the "direction flag", DF).
I tried this:
.data
source DB 'Hello, world!', 0
byte_to_find DB 'o'
.code
MyProc1 proc
std ; Set Direction Flag to 1 (backward direction)
lea rdi, source ; Load address of source string
mov al, byte_to_find ; Load byte to find into AL
mov rcx, 13 ; Length of the source string
SearchLoop:
scasb ; Compare AL with byte at [RSI]
jne NotFound ; Jump if not equal (byte not found)
jmp ByteFound ; Jump if equal (byte found)
NotFound:
mov rax, 0 ; Set RAX to 0 (byte not found)
jmp Done
ByteFound:
mov rax, rdi ; Store the address of the found byte in RAX
dec rax ; Adjust RAX to point to the byte before the found byte
jmp Done
Done:
ret
MyProc1 endp
end
but when I was debugging nothing changed and there still was UP = 1. I also tried using only std and mov after that and there was the same issue.
Searching forward using
scasbrequires setting the direction flag DF to 0. Thecldinstruction does that. What it further requires is that you load the AL register with the character to be found, and the RDI register with the address of the first character of the string.Searching backward using
scasbrequires setting the direction flag DF to 1. Thestdinstruction does that. What it also requires is that you load the AL register with the character to be found, and the RDI register with the address of the last character of the string. Then the formula to use is:And if we plan to use the
repneprefix, we also need to load the RCX register with the length of the string. You can write:You don't need both these jumps. Because the zero flag ZF has but two states, either it's 0 or 1, you can jump to ByteFound if ZF=1, and just fall-through in NotFound if ZF=0.
Although you named this 'SearchLoop', there's no actual loop here! After
scasbhas finished comparing the single byte in AL to the byte in memory ates:[rdi]you immediately jump to one of the two possible exits on the procedure. You need to repeat thescasbinstruction either through prefixing this instruction with therepneprefix (REPeat while Not Equal):or else by writing a normal loop:
Some cleaning is required here, but especially your comment 'Adjust RAX to point to the byte before the found byte' is noteworthy.
I don't know why you would want to return the address before the find, but if that is indeed what you need then know that RDI is already pointing to before the found byte, so you wouldn't need that
dec rax! And should you need to point at the find itself, you would rather have to increment the value:Summary
Searching backward
(*) Whenever you need to use DF=1 locally, you should always return the direction flag to the clear state. Everybody expects to find DF=0, so we shouldn't have to bother using
cldall the time! See The probability of selected EFLAGS bits.Searching forward