News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

Parsing a string for NULL terminator

Started by Lonewolff, April 23, 2018, 03:39:53 PM

Previous topic - Next topic

Lonewolff

Hi guys,

A basic question involving a simple loop.  :biggrin:

I am trying to loop through a null terminated string and have the count until '/0' stored in ecx.

I have a message box in the middle of the loop for debugging purposes only, but am having trouble with an infinite loop.


; loop until '\0'
mov ecx, 0
lp:
invoke MessageBox, 0, addr szBuffer, addr szTitle, 0

mov eax, offset szBuffer
add eax, ecx
cmp eax, 0

inc ecx
jne lp


I am pretty sure I am probably comparing the address itself to zero and not the value.

Any help would be greatly appreciated.  8)

hutch--

This is a simple one. If you want the result in ecx, use ecx instead of eax.

  slen proc pstr:DWORD
    mov eax, pstr
    sub eax, 1
  lbl:
    add eax, 1
    cmp BYTE PTR [eax], 0
    jne lbl
    sub eax, pstr
    ret
  slen endp


For the MessageBox so you don't get problems, use pushad before it and popad after it. Only do this for test code, they are too slow for production code.

What is happening is the code in MessageBox is overwriting the registers you are using.

russellgreen

Quote from: Lonewolff on April 23, 2018, 03:39:53 PM
Hi guys,

A basic question involving a simple loop.  :biggrin:

I am trying to loop through a null terminated string and have the count until '/0' stored in ecx.

I have a message box in the middle of the loop for debugging purposes only, but am having trouble with an infinite loop.


; loop until '\0'
mov ecx, 0
lp:
invoke MessageBox, 0, addr szBuffer, addr szTitle, 0

mov eax, offset szBuffer
add eax, ecx
cmp eax, 0

inc ecx
jne lp


I am pretty sure I am probably comparing the address itself to zero and not the value.

Any help would be greatly appreciated.  8)

mov eax, offset szBuffef
xor ecx, ecx
loopy:
cmp byte ptr [eax+ecx], 0
je endloopy
inc ecx
; message box code
jmp loopy
endloopy:



sorry for the sloppiness, posting from phone




russellgreen

nevermind, listen to hutch.   :biggrin:

I forgot about eax etc getting overwritten   ::)

I'm used to writing buggy code  :icon_mrgreen:

Lonewolff

Thanks guys!

I think the key thing was the 'cmp byte ptr'. This was the main thing that I was struggling with.

I'll have to start taking notes in a word document for these little intricate details.  :t

jj2007

Some more tricks:include \masm32\include\masm32rt.inc

.data
HelloW db "Hello World", 0

.code
start:
; loop until '\0'
xor ecx, ecx ; same as mov ecx, 0 but much shorter
lp:
pushad
invoke MessageBox, 0, addr HelloW[ecx], chr$("Title"), 0
popad
inc ecx
cmp byte ptr HelloW[ecx], 0
jne lp
MsgBox 0, "bye", "Hi", MB_OK  ; a handy Masm32 macro
  exit

end start

Mikl__

; GUI #
include win64a.inc
.data
count db 0
MsgBoxText      db "Win64 Assembly is Great!",0
MsgCaption      db "Uncle Remus tales: #2 MessageBoxIndirect",0
.code
WinMain proc
local mb:MSGBOXPARAMS
mov mb.cbSize,sizeof MSGBOXPARAMS
mov mb.hwndOwner,0
mov mb.hInstance,400000h
        movr mb.lpszText,MsgBoxText
movr mb.lpszCaption,MsgCaption
mov mb.dwStyle,MB_OK or MB_USERICON  or MB_HELP

      mov mb.lpszIcon,1000
      mov mb.dwContextHelpId,0
  mov mb.lpfnMsgBoxCallback,0
  mov mb.dwLanguageId,0
mov count,lengthof MsgBoxText
@@: lea ecx,mb
invoke MessageBoxIndirect
sub count,1
jnz @b
invoke RtlExitUserProcess,NULL
WinMain endp
end
; GUI #
include win64a.inc
.data
MsgBoxText      db "Win64 Assembly is Great!",0
MsgCaption      db "Uncle Remus tales: #2 MessageBoxIndirect",0
count db 0
.code
WinMain proc
local mb:MSGBOXPARAMS
mov mb.cbSize,sizeof MSGBOXPARAMS
mov mb.hwndOwner,0
mov mb.hInstance,400000h
        movr mb.lpszText,MsgBoxText
movr mb.lpszCaption,MsgCaption
mov mb.dwStyle,MB_OK or MB_USERICON  or MB_HELP

      mov mb.lpszIcon,1000
      mov mb.dwContextHelpId,0
  mov mb.lpfnMsgBoxCallback,0
  mov mb.dwLanguageId,0
mov edi,offset MsgBoxText
or ecx,-1
mov al,0
repne scasb
not ecx
mov count,cl
@@: lea ecx,mb
invoke MessageBoxIndirect
sub count,1
jnz @b
invoke RtlExitUserProcess,NULL
WinMain endp
end

LordAdef

Wolff,

Are you using the messageBox for debugging purposes?

If yes, I'd suggest you make a custom macro. It's really useful in these cases.

This is mine, simple and yet efficient:


console MACRO tt:REQ, tt2:VARARG
   PUSHAD
   printf (&tt, &tt2)
   printf ("\n")
   POPAD
endm

This is a nice approach. If you filled your code with this debug macro and temporarily want to bypass it, simply go to the macro and comment its code. Fast and easy

Lonewolff

Hi Lord,

Thanks for the code snippet and yep, it's for debugging.

Today, I'll take a step back and work more on the basics. Like a lot of eager newbies, I started my journey in the middle (which isn't a bad thing, I don't think).

I have had a taste and I know I can achieve what I want to do. My initial challenge was 'can I set up DirectX11 and draw a quad?'. I did that and much much more.   8)

So back to basics I go now  :t

LordAdef

Quote from: Lonewolff on April 24, 2018, 07:55:01 AM
Hi Lord,

Thanks for the code snippet and yep, it's for debugging.

Today, I'll take a step back and work more on the basics. Like a lot of eager newbies, I started my journey in the middle (which isn't a bad thing, I don't think).

I have had a taste and I know I can achieve what I want to do. My initial challenge was 'can I set up DirectX11 and draw a quad?'. I did that and much much more.   8)

So back to basics I go now  :t

Sweet!
Well, it makes life a lot easier, and it's simple because of what I mentioned.

console "This is a printf   %d   %d", eax, ebx

Lonewolff

Thanks man!

Learning bucket loads each day. I'm like a big old sponge  :lol:

LordAdef

Quote from: Lonewolff on April 24, 2018, 09:45:12 AM
Thanks man!

Learning bucket loads each day. I'm like a big old sponge  :lol:

Me too!!!!

aw27

A professional :shock:  debugging alternative that does not create noise in the console and does not pop alien windows. And it integrates with the masm32 sdk.
You will use dbgview.exe to see what happens.


include \masm32\include\masm32rt.inc

DEBUGGING equ 1 ; Comment when done with debugging

dbg MACRO format:REQ, args:VARARG
    LOCAL dbg_buffer

IFDEF DEBUGGING
    .data
dbg_buffer byte 80 dup (0)
    .code
    pushad
    IFNB <args>
        fn crt_sprintf, offset dbg_buffer, cfm$(format), args
        fn OutputDebugStringA, offset dbg_buffer
    ELSE
        fn OutputDebugStringA, cfm$(format)
    ENDIF
    popad
ENDIF
ENDM

.code

main proc
dbg "Testing OutputDebugString"
dbg "Some string: %s, some value: %d", "hello there", 12

invoke ExitProcess,0
main endp

end main

jj2007

Quote from: aw27 on April 24, 2018, 07:30:25 PM
A professional :shock:  debugging alternative that does not create noise in the console and does not pop alien windows. And it integrates with the masm32 sdk.
You will use dbgview.exe to see what happens.

Didn't see any output until I added ; OPT_Debug 1 (RichMasm's special features ;))
Quote from: jj2007 on July 01, 2016, 09:22:42 AM
OPT_Debug       1                       ; enable the heap debugger (useful if you suspect heap corruption; console only)

I know what you are doing but it's not obvious. Perhaps you should elaborate a little bit for the n00bs here. I am also curious what you mean with "does not create noise in the console". The output goes to the console, right?

aw27

@JJ,

You will see the debug strings either with DbgView.exe from Microsoft, or, if you are using a debugger, you will see the output in the debugger output window only. So, the first one that grabs it is the one that views it because they are event based.
You can also produce your own "dbgview.exe", but will not be as powerful as DbgView.exe because this one works from kernel mode and can capture also ring 0 debug strings and user mode debug strings from different sessions (including when you launch the application as Administrator or another user).

Quote
Didn't see any output until I added ; OPT_Debug 1 (RichMasm's special features ;))
After my explanation, may be you can infer, and eventually fix the RichMasm problem.

Quote
The output goes to the console, right?
No, it does not, it appears in DbgView window.