Author Topic: .while  (Read 919 times)

fertxo

  • Regular Member
  • *
  • Posts: 2
.while
« on: November 20, 2021, 10:12:45 PM »
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?

rsala

  • Moderator
  • Member
  • *****
  • Posts: 348
    • Easy Code
Re: .while
« Reply #1 on: November 20, 2021, 10:24:18 PM »
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.
EC coder

fertxo

  • Regular Member
  • *
  • Posts: 2
Re: .while
« Reply #2 on: November 20, 2021, 11:26:18 PM »
 :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.

jj2007

  • Member
  • *****
  • Posts: 12471
  • Assembler is fun ;-)
    • MasmBasic
Re: .while
« Reply #3 on: November 21, 2021, 04:01:20 AM »
Check the instr() macro

rsala

  • Moderator
  • Member
  • *****
  • Posts: 348
    • Easy Code
Re: .while
« Reply #4 on: November 21, 2021, 07:13:24 AM »
Hi jj2007,

Thanks for your help!  :thumbsup:
EC coder

jj2007

  • Member
  • *****
  • Posts: 12471
  • Assembler is fun ;-)
    • MasmBasic
Re: .while
« Reply #5 on: November 21, 2021, 12:17:01 PM »
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 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:

Code: [Select]
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

rsala

  • Moderator
  • Member
  • *****
  • Posts: 348
    • Easy Code
Re: .while
« Reply #6 on: November 21, 2021, 08:58:38 PM »
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.
EC coder

nidud

  • Member
  • *****
  • Posts: 2390
    • https://github.com/nidud/asmc
Re: .while
« Reply #7 on: November 21, 2021, 10:38:54 PM »
deleted
« Last Edit: February 26, 2022, 05:23:55 AM by nidud »

rsala

  • Moderator
  • Member
  • *****
  • Posts: 348
    • Easy Code
Re: .while
« Reply #8 on: November 22, 2021, 07:50:21 AM »
Good example Nidud!

But since there are functions for compare two strings, I still do not see the need of using .while.
EC coder

jj2007

  • Member
  • *****
  • Posts: 12471
  • Assembler is fun ;-)
    • MasmBasic
Re: .while
« Reply #9 on: November 22, 2021, 09:51:59 AM »
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:
Code: [Select]
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:
Code: [Select]
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