News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

String mystery

Started by IanScott, May 17, 2013, 07:24:51 AM

Previous topic - Next topic

IanScott

In the following code, the local variable 'character' is defined as a 2 byte array in the getURL proc. When the program executes the string "ASMProject.exe www.smh.com.au" displays correctly. However changing the size of the variable from 2 bytes to 1 byte displays garbage like

A$¨"S$¨"M$¨"P$¨"r$¨"o$¨"j$¨"e$¨"c$¨"t$¨".$¨"e$¨"x$¨"e$¨" $¨"w$¨"w$¨"w$¨".$¨"s$¨"
m$¨"h$¨".$¨"c$¨"o$¨"m$¨".$¨"a$¨"u$¨"

If you look closely at the garbage all of the characters from the string "ASMProject.exe www.smh.com.au" are there with the addition of other characters.

Here is the code

.586
.model flat, stdcall

option casemap:none

include \masm32\include\masm32rt.inc

.data

commandLine     db "ASMProject.exe www.smh.com.au",0

.code

start:          call getURL   
                invoke ExitProcess, eax

; -------------------------------------------------------------------------------
getURL      proc
                Local character[2]:BYTE

                cld                                              ; clear the direction flag
                lea esi, commandLine

@@:         lodsb                                           ; load byte from source into al
                mov character, al                         ; move byte to the character variable
               
                invoke StdOut, addr character       ; write character to console
                cmp al, 0                                     ; 0 means end of the string
                jne @B

                call crt__getch
                ret
getURL     endp
               end start


I know that al is one byte in length so moving a byte from al into the 'character' variable should not cause a problem should it ? If I need two bytes to correctly display the string then what is the extra byte used for ?

Thanks

jj2007

You are printing a string that starts at character[0] (addr character) and ends... well... somewhere. Remember that local variables may contain garbage. So to print exactly one char, you need to explicitly delimit the string with mov character[1], 0:
                lea esi, commandLine
                mov character[1], 0                      ; move byte to the character variable

@@:         lodsb                                           ; load byte from source into al
                cmp al, 0                                     ; 0 means end of the string
                je @F
                mov character, al                         ; move byte to the character variable
               
                invoke StdOut, addr character       ; write character to console
                jmp @B
@@:


Another little point: StdOut returns "no value", but in reality it just means eax may be zero or non-zero. You can't use eax (or al) after StdOut to check the end of your string.

IanScott

Thanks jj that makes sense about local variables potentially containing garbage. I have also come across a few problems with StdOut and the eax register in the past and resorted to pushing eax before calling StdOut. What you wrote explains why there was an issue.

hutch--

Aha, another Sydneysider.  :t