2012-05-21 3 views
0

J'ai créé ce programme qui prend deux entrées et les imprime (simple, oui, mais c'est pour la pratique). Il compile et fonctionne bien, mais il ne fait pas ce que je voulais. Voici mon code:x86 assembly - masm32: Problèmes d'attente de réponse

.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 

Il affiche cette sortie:

Enter a number: Enter another number: 

Il devrait faire:

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

Pourquoi faut-il imprimer sur une seule ligne? J'ai essayé d'y mettre halt pour arrêter le processus, mais Windows arrête le programme et dit the program is not responding.

EDIT:

Voici le code que je l'ai dit je modifier dans:

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

Quand je lance ce avec le code précédent, il dit "This program is not responding." Pourquoi est-ce?

Toute aide serait appréciée.

Cordialement,

Progrmr

+0

Pourquoi ne serait-il imprimer sur une seule ligne? Thats ce qu'il fait, vous devez ajouter 13, 10 après votre texte. De plus, votre tampon pour contenir du texte devrait être db pas dd sauf si vous voulez vraiment un tampon de 400 octets. – Gunner

+0

Cela le déplace vers une autre ligne, merci. Mais il n'attend toujours pas d'entrée, il montre à la fois num1 et num2 et n'attend pas d'entrée. Pourquoi? – Progrmr

Répondre

3

HLT sera, évidemment, l'exécution de l'arrêt. Il doit uniquement être utilisé pour attendre l'interruption matérielle suivante et ne doit être utilisé que par le système d'exploitation. StdIn ne fonctionne pas pour vous, car vous n'indiquez pas la longueur de la mémoire tampon.

StdIn échoue donc et le prochain StdOut est exécuté.

N'utilisez pas hlt, et appuyez sur la longueur du tampon, puis appuyez sur l'adresse pour le tampon.

.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 

Sortie: Output

stdcall dicte que vous appuyez sur les paramètres de droite à gauche. En outre, vous pouvez bénéficier de l'examen du code pour StdIn et 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

Merci Motes. Une dernière question: quand j'ai exécuté le code, ça a marché. Mais quand le programme est arrivé à la partie où il imprime les entrées, il dit 'Ce programme ne répond pas. Mon code qui suit votre exemple est édité dans le message. Pouvez-vous m'aider? – Progrmr

+0

Etes-vous sûr que vous avez supprimé l'instruction hlt? De même, il n'est pas nécessaire d'utiliser plusieurs registres ou de les effacer avec xor. J'ai mis à jour le code que j'ai fourni pour fournir un exemple de travail complet, avec la sortie. – Motes

+0

Cool, merci. Cela fonctionne très bien. Merci pour l'aide. – Progrmr

Questions connexes