2012-05-21 1 views
0

Я создал эту программу, которая берет два входа и выводит их (просто, да, но это для практики). Он компилируется и работает нормально, но он не делает того, что я намеревался. Вот мой код:x86 assembly - masm32: Проблемы с ожиданием ответа

.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 

Он отображает этот выход:

Enter a number: Enter another number: 

Он должен сделать:

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

Почему печать на одной строке? Я попытался поставить halt там, чтобы остановить процесс, но Windows останавливает запуск программы и говорит the program is not responding.

EDIT:

Вот код, который я сказал, что отредактированные в:

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

Когда я запускаю это с предыдущим кодом, он говорит "This program is not responding." Почему это?

Любая помощь будет оценена по достоинству.

С уважением,

Progrmr

+0

Почему бы не это печатать на одную строке? То, что он делает, вам нужно добавить 13, 10 после вашего текста. Кроме того, ваш буфер для хранения текста должен быть db не dd, если вы действительно не хотите буфера в 400 байт. – Gunner

+0

Это переводит его на другую линию, спасибо. Но он все еще не ждет ввода, он показывает как num1, так и num2, а затем не ждет ввода. Зачем? – Progrmr

ответ

3

HLT будет, ясно, исполнение привал. Он должен использоваться только для ожидания следующего аппаратного прерывания и должен использоваться только операционной системой.

StdIn не работает для вас, потому что вы не предоставляете длину буфера. Таким образом, StdIn терпит неудачу, и выполняется следующий StdOut.

Не используйте hlt и нажимайте длину буфера, а затем нажимайте адрес в буфер.

.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

STDCALL диктует нажимаешь параметры справа налево. Кроме того, вы могли бы извлечь выгоду из анализа кода для STDIN и 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 
+0

Спасибо Motes. Последний вопрос: когда я запускал код, он работал с удовольствием. Но когда программа пришла к той части, где она печатает входные данные, она говорит: «Эта программа не отвечает. Мой код, следующий за вашим примером, редактируется в сообщении. Вы можете мне помочь? – Progrmr

+0

Вы уверены, что удалили инструкцию hlt? Кроме того, нет необходимости использовать несколько регистров или очистить их с помощью xor. Я обновил код, который я предоставил, чтобы предоставить полный рабочий пример вместе с выходом. – Motes

+0

Прохладный, спасибо. Это отлично работает. Спасибо за помощь. – Progrmr