Search code examples
assemblyinputx86masmmasm32

x86 assembly - masm32: Issues with waiting for response


I have created this program that takes two inputs and prints them out (simple, yes, but it's for practise). It compiles, and runs fine, but it doesn't do what I intended. Here is my code:

.386 
.model flat, stdcall 
option casemap :none 
include \masm32\include\windows.inc 
include \masm32\include\kernel32.inc 
include \masm32\include\masm32.inc 
includelib \masm32\lib\kernel32.lib 
includelib \masm32\lib\masm32.lib
.data 
   num1 db "Enter a number:", 0 
   num2 db "Enter another number:", 0
.data? 
       buffer1 dd 100 dup(?)
   buffer2 dd 100 dup(?)
.code 
start:
   lea eax, num1
   push eax
   call StdOut
   lea ebx, buffer1
   push ebx
   call StdIn
   hlt
   lea eax, num2
   push eax
   call StdOut
   lea edx, buffer2
   push edx
   call StdIn
   xor eax, eax
   xor ebx, ebx
   xor edx, edx
   lea eax, buffer1
   push eax
   call StdOut
   lea ebx, buffer2
   push ebx
   call StdOut
   push 0 
   call ExitProcess
end start 

It displays this output:

Enter a number: Enter another number:

It should do:

Enter a number:
; wait for input.
Enter another number:
; wait for input.
; continue with program.

Why does it print on one line? I tried putting halt in there to stop the process, but Windows stops the program from running, and says the program is not responding.

EDIT:

Here is the code that I said I would edit in:

xor eax, eax
xor ebx, ebx
xor edx, edx
lea eax, buffer1
push eax
call StdOut
lea ebx, buffer2
push ebx
call StdOut

When I run this with the previous code, it says "This program is not responding." Why is this?

Any help would be appreciated.

Regards,

Progrmr


Solution

  • hlt will, plainly, halt execution. It should only be used to wait for the next hardware interrupt, and should only be used by the operating system.

    StdIn isn't working for you, because you aren't providing the length of buffer. So StdIn fails and the next StdOut is executed.

    Don't use hlt, and push the length of buffer and then push the address to buffer.

    .386 
    .model flat, stdcall 
    option casemap :none 
    
    include \masm32\include\windows.inc 
    include \masm32\include\kernel32.inc 
    include \masm32\include\masm32.inc 
    include \masm32\include\msvcrt.inc 
    include \MASM32\INCLUDE\user32.inc
    
    includelib \masm32\lib\kernel32.lib 
    includelib \masm32\lib\masm32.lib
    includelib \masm32\lib\msvcrt.lib
    includelib \MASM32\LIB\user32.lib
    
    atoi PROTO C strptr:DWORD
    
    .data 
       num1 db "Enter a number:", 0 
       num2 db "Enter another number:", 0
       formatStr db "%s+%s=%d", 0
    
    .data? 
       buffer1 dw 100 dup(?)
       buffer2 dw 100 dup(?)
       buffer3 dw 100 dup(?)
    .code 
    start:
       lea eax, num1
       push eax
       call StdOut
    
       mov eax,100
       push eax
       lea eax, buffer1
       push eax
       call StdIn
    
       lea eax, num2
       push eax
       call StdOut
    
       mov eax,100
       push eax
       lea eax, buffer2
       push eax
       call StdIn
    
       lea eax, buffer1
       push eax
       call atoi
       mov ebx,eax
    
       lea eax, buffer2
       push eax
       call atoi 
       add eax,ebx
    
       push eax
       lea eax,buffer2
       push eax
       lea eax,buffer1
       push eax
       lea eax,formatStr
       push eax
       lea eax,buffer3
       push eax
       call wsprintf
    
    
       lea eax,buffer3
       push eax
       call StdOut
    
       push 0 
       call ExitProcess
    
    end start
    

    Output: Output

    stdcall dictates you push parameters from right to left. Also, you might benefit from reviewing the code for StdIn and StdOut:

    StdIn proc lpszBuffer:DWORD,bLen:DWORD
    
       LOCAL hInput :DWORD
       LOCAL bRead  :DWORD
    
       invoke GetStdHandle,STD_INPUT_HANDLE
       mov hInput, eax
    
       invoke SetConsoleMode,hInput,ENABLE_LINE_INPUT or \
                                    ENABLE_ECHO_INPUT or \
                                    ENABLE_PROCESSED_INPUT
    
       invoke ReadFile,hInput,lpszBuffer,bLen,ADDR bRead,NULL
    
       mov eax, bRead
    
       ret
    
    StdIn endp
    
    StdOut proc lpszText:DWORD
    
        LOCAL hOutPut  :DWORD
        LOCAL bWritten :DWORD
        LOCAL sl       :DWORD
    
        invoke GetStdHandle,STD_OUTPUT_HANDLE
        mov hOutPut, eax
    
        invoke StrLen,lpszText
        mov sl, eax
    
        invoke WriteFile,hOutPut,lpszText,sl,ADDR bWritten,NULL
    
        mov eax, bWritten
        ret
    
    StdOut endp