Readconsole не работает из подпрограммы - Assembler

Узнай цену своей работы

Формулировка задачи:

В основной программе вводится, а в процедуре "проходит мимо". Причем не работает на домашнем компьютере (xp sp3) а на рабочем (win7) работает нормально. Или может есть более правильный способ ввода в винде?
 .386 ; 32-битный режим 
 .model flat, stdcall                   ; компиляция в exe-файл с возможностью вызова API 
 option casemap :none                   ; неразличение прописных и строчных символов 
                                        ; содержит значения констант 
include C:\masm32\include\windows.inc   ; STD_INPUT_HANDLE, 
                                        ; STD_OUTPUT_HANDLE 
include C:\masm32\include\kernel32.inc 
include C:\masm32\include\user32.inc 
 
includelib <\masm32\lib\kernel32.lib> 
includelib <\masm32\lib\user32.lib> 
 
.data                                   ; сегмент данных 
 
hConsoleInput DWORD ?                   ; переменные для хранения хэндлов ввода и вывода, 
hConsoleOutput DWORD ?                  ; названия этих переменных могут быть другими 
 
                                        ; буфер 6 байт (со значением 0) 
Buffer byte 12 dup (0)                   ; для вода с клавиатуры 1 символа, \
                                        ; название буфера может быть другим 
 
NumberOfCharsRead DWORD ?               ; переменные для записи числа фактически 
NumberOfCharsWritten DWORD ?            ; введенных и выведенных символов, 
                                        ; названия этих переменных могут быть другими 
    
msgErr byte "Error!",13, 10             ; строковая переменная 
msgEnterN byte "Enter N",13, 10         ; строковая переменная 
msgEnterM byte "Enter M",13, 10         ; строковая переменная 
msgEnterA byte "Enter matrix A",13, 10  ; строковая переменная 
msgMatr byte "Matrix A",13, 10          ; строковая переменная 
msg1310 byte 13, 10                     ; перевод строки 
 
N       word    ?
M       word    ?
A       word    10000 dup(?)
Sum     DWORD   ?
.code                                   ; сегмент кода 
start: 
 
    invoke AllocConsole                     ; запрашиваем у Windows консоль 
 
    invoke GetStdHandle, STD_INPUT_HANDLE   ; получаем хэндл консоли для ввода 
    mov hConsoleInput, EAX                  ; записываем хэндл в переменную 
 
    invoke GetStdHandle, STD_OUTPUT_HANDLE  ; получаем хэндл консоли для вывода 
    mov hConsoleOutput, EAX                 ; записываем хэндл в переменную 
 
    invoke  WriteConsoleA,  ; переводим строку в консоли 
           hConsoleOutput,  ; хэндл вывода 
             ADDR msg1310,  ; адрес строки msg1310 
           SIZEOF msg1310,  ; размер строки msg1310
ADDR NumberOfCharsWritten,  ; сюда функция запишет число символов 
                        0   ; lpReserved передаем, как ноль 
                            ; пишем "Enter N"           
    invoke  WriteConsoleA, hConsoleOutput, ADDR msgEnterN, SIZEOF msgEnterN, ADDR NumberOfCharsWritten, 0 
    call    inputnumber;
    mov     N,ax
                            ; пишем "Enter M" 
    invoke  WriteConsoleA, hConsoleOutput, ADDR msgEnterM, SIZEOF msgEnterM, ADDR NumberOfCharsWritten, 0 
    call    inputnumber;
    mov     M,ax
                            ; пишем "Enter A" 
    invoke  WriteConsoleA, hConsoleOutput, ADDR msgEnterA, SIZEOF msgEnterA, ADDR NumberOfCharsWritten, 0
    mov     eax, offset A
    mov     ecx,0
    mov     cx,N
    mov     esi,0
inAc1:
    push    cx
    mov     cx,M
    mov     ebx,0
inAc2:
    call    inputnumber;
    mov     A[ebx+esi],ax
    inc     esi
    inc     esi
    loop    inAc2
    add     ebx,esi
    pop     cx
    loop    inAc1
 
    mov     ax,N
    call    printnumber
    mov     ax,M
    call    printnumber
                            ;"\nMatrix A\n "
    invoke  WriteConsoleA, hConsoleOutput, ADDR msg1310, SIZEOF msg1310, ADDR NumberOfCharsWritten, 0
    invoke  WriteConsoleA, hConsoleOutput, ADDR msgMatr, SIZEOF msgMatr, ADDR NumberOfCharsWritten, 0
    mov     ecx,0
    mov     cx,N
    mov     si,0
outAc1:
    push    ecx
    mov     cx,M
outAc2:
    mov     ax,A[si]
    call    printnumber;
    inc     si
    inc     si
    loop    outAc2
                            ;"\n"
    invoke  WriteConsoleA, hConsoleOutput, ADDR msg1310, SIZEOF msg1310, ADDR NumberOfCharsWritten, 0
    pop     ecx
    loop    outAc1
    
    push    [N];   n
    push    [M];   m,n
    push    offset A;   a,m,n
    CALL    calc_m
    mov     Sum,eax
    call    printnumber32;
 
    invoke  ReadConsoleA,   ; ожидаем ввода в консоль 
           hConsoleInput,   ; хэндл ввода 
             ADDR Buffer,   ; адрес буфера 
                       1,   ; вводим 7 символ 
   ADDR NumberOfCharsRead,   ; сюда функция запишет число символов 
                        0   ; lpReserved передаем, как ноль

    invoke ExitProcess, 0   ; сообщаем системе, что программа окончена 
 
                            ;Процедура вводит число с клавиатуры и
                            ;возвращает его в регистре AX
inputnumber     proc near
                            ;Сохранение используемых регистров
    push    bx
    push    si
    push    di
    push    ecx
m_beg:                      ; ожидаем ввода в консоль (но ничего не вводится)
    invoke  ReadConsoleA, hConsoleInput, ADDR Buffer, 8, ADDR NumberOfCharsRead, 0
    mov     cx,10
    mov     ax,0
    mov     bx,0
    mov     si,0            ;
    mov     di,1            ;
    mov     bl,Buffer[si]   ;
    cmp     bl,13
    je      m_beg           ;
    cmp     bl,'-'          ;
    jne     imcycle         ;
    mov     di,-1           ;
    inc     si              ;
    je      m_err           ;
imcycle:
    mov     bl,Buffer[si]   ;
    cmp     bl,13
    je      end_imp         ;
    cmp     bl,'0'          ;символ
    jb      m_err           ;цифрой?
    cmp     bl,'9'  
    ja      m_err   
    sub     bl,30h          ;От кода символа вычитаем 30h и получаем
    imul    cx 
    jo      m_err           ;При переполнении переходим
    add     ax,bx           ;к обработке ошибки.
    jo      m_err           ;Это означает, что введено число,
    inc     si              ;которое не помещается в поле слова.
    jmp     imcycle         ;
m_err:
    invoke WriteConsoleA,   ; пишем "Error!" 
           hConsoleOutput, 
              ADDR msgErr, 
            SIZEOF msgErr, 
ADDR NumberOfCharsWritten, 
                         0
    jmp     m_beg           ;
end_imp:
    imul    ax,di;
 
    pop     ecx
    pop     di
    pop     si
    pop     bx
    RET
 
inputnumber endp
 
printnumber     proc    near
    push    bx
    push    ecx
    push    dx
    push    esi
    
    mov     ecx,8            ;Обнуление строки S для вывода числа
    mov     esi,offset Buffer
    mov     dl,' '
met: 
    mov     [esi],dl
    inc     si
    loop    met
    dec     si
    mov     bx,10           ; Основание десятичной сист. счисл.
;Определяем знак числа  
    mov     cl,' '          ;Используем пробел в качестве знака '+'
    cmp     ax,0    
    jge     met_1    
    mov     cl,'-'  
    neg     ax 
met_1:   
    mov     dx,0
    idiv    bx  
    add     dl,30h          ;К остатку в DL прибавим 30h и получим
                                ;символ цифры
    mov     [esi],dl    
    dec     si  
    cmp     ax,0            ;В АХ частное. Когда АХ=0, то завершаем перевод
    jne     met_1    
    mov     [esi],cl        ;Заносим знак в строку и
    invoke  WriteConsoleA, hConsoleOutput, ADDR Buffer, 8, ADDR NumberOfCharsWritten, 0 
 
    pop     esi
    pop     dx
    pop     ecx
    pop     bx
    ret
printnumber endp
 
printnumber32     proc    near
    push    ebx
    push    ecx
    push    edx
    push    esi
    
    mov     ecx,12            ;Обнуление строки S для вывода числа
    mov     esi,offset Buffer
    mov     dl,' '
met32: 
    mov     [esi],dl
    inc     si
    loop    met32
    dec     si
    mov     ebx,10          ; Основание десятичной сист. счисл.
;Определяем знак числа  
    mov     cl,' '          ;Используем пробел в качестве знака '+'
    cmp     eax,0    
    jge     met32_1    
    mov     cl,'-'  
    neg     eax 
met32_1:   
    mov     edx,0
    idiv    ebx  
    add     dl,30h          ;К остатку в DL прибавим 30h и получим
                                ;символ цифры
    mov     [esi],dl    
    dec     si  
    cmp     eax,0           ;В АХ частное. Когда АХ=0, то завершаем перевод
    jne     met32_1    
    mov     [esi],cl        ;Заносим знак в строку и
    invoke  WriteConsoleA, hConsoleOutput, ADDR Buffer, SIZEOF Buffer, ADDR NumberOfCharsWritten, 0 
 
    pop     esi
    pop     edx
    pop     ecx
    pop     ebx
    ret
printnumber32 endp

calc_m PROC             ;4
    push    ebp;        ;8(A),12(M),14(N)    
    mov     ebp,esp;
    push    ebx;          
    push    ecx;        
    push    edx;        
    push    esi;        
    push    edi;        
    mov     ebx,[ebp+8];
    mov     eax,0
 
    mov     ecx,0
    mov     edx,0
    mov     cx,[ebp+14];
cAc1:
    push    cx 
    push    eax
    mov     cx,[ebp+12];
    mov     eax,ecx
    mov     di,2
    mov     edx,0
    idiv    di
    add     ax,dx
    mov     ecx,eax
    pop     eax
    mov     esi,0
cAc2:
    mov     dx,[ebx+esi]
    add     eax,edx
    inc     esi
    inc     esi
    inc     esi
    inc     esi
    loop    cAc2
    mov     cx,[ebp+12];
    add     ebx,ecx
    add     ebx,ecx
    pop     cx
    loop    cAc1
    pop     edi
    pop     esi
    pop     edx
    pop     ecx
    pop     ebx
    pop     ebp
    RET     8
calc_m ENDP 

end start                               ; завершает сегмент кода

Решение задачи: «Readconsole не работает из подпрограммы»

textual
Листинг программы
mov     esi,offset Buffer
...........
.............
.........
mov     bl,[esi]        ;

Оцени полезность:

13   голосов , оценка 3.923 из 5