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] ;