Author Topic: Parsing a string for NULL terminator  (Read 1034 times)

Ascended

  • Member
  • ***
  • Posts: 331
Parsing a string for NULL terminator
« 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.

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

  • Administrator
  • Member
  • ******
  • Posts: 5831
  • Mnemonic Driven API Grinder
    • The MASM32 SDK
Re: Parsing a string for NULL terminator
« Reply #1 on: April 23, 2018, 03:49:37 PM »
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.
hutch at movsd dot com
http://www.masm32.com    :biggrin:  :biggrin:

-infinity

  • Regular Member
  • *
  • Posts: 19
Re: Parsing a string for NULL terminator
« Reply #2 on: April 23, 2018, 03:52:36 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.

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




-infinity

  • Regular Member
  • *
  • Posts: 19
Re: Parsing a string for NULL terminator
« Reply #3 on: April 23, 2018, 03:54:42 PM »
nevermind, listen to hutch.   :biggrin:

I forgot about eax etc getting overwritten   ::)

I'm used to writing buggy code  :icon_mrgreen:

Ascended

  • Member
  • ***
  • Posts: 331
Re: Parsing a string for NULL terminator
« Reply #4 on: April 23, 2018, 04:07:00 PM »
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

  • Member
  • *****
  • Posts: 8773
  • Assembler is fun ;-)
    • MasmBasic
Re: Parsing a string for NULL terminator
« Reply #5 on: April 23, 2018, 05:02:56 PM »
Some more tricks:
Code: [Select]
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__

  • Member
  • ****
  • Posts: 686
Re: Parsing a string for NULL terminator
« Reply #6 on: April 23, 2018, 11:07:19 PM »
Code: [Select]
; 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
Code: [Select]
; 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

  • Member
  • ****
  • Posts: 590
Re: Parsing a string for NULL terminator
« Reply #7 on: April 24, 2018, 02:47:54 AM »
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

Ascended

  • Member
  • ***
  • Posts: 331
Re: Parsing a string for NULL terminator
« Reply #8 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

LordAdef

  • Member
  • ****
  • Posts: 590
Re: Parsing a string for NULL terminator
« Reply #9 on: April 24, 2018, 09:44:09 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

Ascended

  • Member
  • ***
  • Posts: 331
Re: Parsing a string for NULL terminator
« Reply #10 on: April 24, 2018, 09:45:12 AM »
Thanks man!

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

LordAdef

  • Member
  • ****
  • Posts: 590
Re: Parsing a string for NULL terminator
« Reply #11 on: April 24, 2018, 11:24:28 AM »
Thanks man!

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

Me too!!!!

AW

  • Member
  • *****
  • Posts: 1500
  • Let's Make ASM Great Again!
Re: Parsing a string for NULL terminator
« Reply #12 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.

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

  • Member
  • *****
  • Posts: 8773
  • Assembler is fun ;-)
    • MasmBasic
Re: Parsing a string for NULL terminator
« Reply #13 on: April 24, 2018, 10:51:15 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 ;))
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?

AW

  • Member
  • *****
  • Posts: 1500
  • Let's Make ASM Great Again!
Re: Parsing a string for NULL terminator
« Reply #14 on: April 25, 2018, 12:01:28 AM »
@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.