hello, I don't know how to use the .while instruction. I'm trying to compare two strings and a want to use that instruction.
Can to help me anyone?
Hi fertxo,
What do you exactly want to do? If you just want to compare two strings, you can use the "Cmp" instruction like this:
32-bit
====
Mov Eax, String1
Cmp Eax, String2
64-bit
====
Mov Rax, String1
Cmp Rax, String2
Take into account that you cannot compare (or any other operation) two strings, that is, two memory addresses in assembler. So, you have to load in a register at least one of them.
:thup:thanks, I just wanna try another way to compare two strings. the messagebox must advice if the second string is inside on first string.
Check the instr() macro
Hi jj2007,
Thanks for your help! :thumbsup:
Ramon, my advice was actually wrong :sad:
> the messagebox must advice if the second string is inside on first string
@fertxo: There is no Instr() macro (https://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1153) in the Masm32 SDK, it's called Find$(startpos, pSource$, pPattern$) and sits in \masm32\macros\macros.asm.
However, your question re .While indicates that you wish to check if two strings are identical. That is difficult with .While but easy with .Repeat ... .Until:
include \masm32\include\masm32rt.inc
.code
start:
.if find$(1, "Hello World", "World")
push eax
print "The substring 'World' was found at position "
pop eax
print str$(eax), 13, 10
.else
print "The substring 'World' was not found", 13, 10
.endif
mov esi, chr$("Hello World, how are you?")
mov edi, chr$("Hello Word, how are you?")
dec edi ; we start at pos -1, so that the first inc is at position 0
.Repeat
inc edi ; advance second string
lodsb ; mov al, [esi] & inc esi
.Until al!=byte ptr [edi]
print "These parts of the strings are not equal:", 13, 10
dec esi
print esi, 13, 10
dec edi
inkey edi, 13, 10
exit
end start
jj2007, thanks for your interest anyway! :thumbsup:
Another easy way to compare two strings is by using the lstrcmp and/or lstrcmpi API functions.
Case insensitive:
==========
Mov Eax, string1
Invoke lstrcmpi, Eax, string2
.If Eax == 0
; string1 and string2 are equal
.EndIf
Case sensitive:
==========
Mov Eax, string1
Invoke lstrcmp, Eax, string2
.If Eax == 0
; string1 and string2 are equal
.EndIf
I do not see the need of using ".While" to compare two strings.
Regards.
deleted
Good example Nidud!
But since there are functions for compare two strings, I still do not see the need of using .while.
The .while 1 is actually a bit fake, as there is no real condition tested - basically an endless loop, from which you can exit only using a .break
Here is a version that uses the .Repeat ... .Until construct:
include \Masm32\MasmBasic\Res\JBasic.inc ; ## builds in 32- or 64-bit mode with UAsm & AsmC but not ML64 ##
.code
CompareTwoStrings proc a:SIZE_P, b:SIZE_P ; receives two pointers
xor eax, eax ; result
mov rcx, a
mov rdx, b
.Repeat
mov al, [rcx]
.if !al ; end of string a ?
cmp al, [rdx]
je equal ; return 0 if equal
.break
.endif
inc rcx
inc rdx
.Until al != [rdx-1]
sbb eax, eax ; return -1 or 1
sbb eax,-1
equal:
ret
CompareTwoStrings endp
Init ; OPT_64 0 ; put 0 for 32 bit, 1 for 64 bit assembly
PrintLine Chr$("This program was assembled with ", @AsmUsed$(1), " in ", jbit$, "-bit format.")
jinvoke CompareTwoStrings, Chr$("Hello World, this is string A"), Chr$("Hello World, that is string B")
Print Str$("Result unequal:\t%i\n", rax)
jinvoke CompareTwoStrings, Chr$("Hello World, this is a string"), Chr$("Hello World, this is a string")
Print Str$("Result equal:\t%i\n", rax)
EndOfCode
Output for OPT_64 1 and OPT_64 0:
This program was assembled with AsmC in 64-bit format.
Result unequal: 1
Result equal: 0
This program was assembled with UAsm64 in 32-bit format.
Result unequal: 1
Result equal: 0