Хочу сделать что-то вроде зелёного экрана из "Матрицы". Столкнулся с такой проблемой, апишная функция ReadConsoleOutputCharacter ругается и не работает (см. комментарии). Спасибо всем, кто ответит. Код (Text): .486 .model flat,stdcall option casemap:none includelib ../lib/kernel32.lib include ../include/windows.inc include ../include/kernel32.inc .const sConsoleTitle db 'Random',0 .data dMultiplier dd 16807d ;данные для генерирования случайных чисел dDivider dd 2147483647d sLine db 80 dup(48) ;2 буфера для двух строк sTmpLine db 80 dup(30h) dTmp dd 0 ;здесь хранится последнее случайное число ;нужно только для генерирования следующего .code Main PROC LOCAL hStdout :DWORD ;получаем хендл консольного вывода invoke SetConsoleTitle, offset sConsoleTitle invoke GetStdHandle, STD_OUTPUT_HANDLE mov hStdout, eax ;делаем текст зелёным invoke FillConsoleOutputAttribute, hStdout, FOREGROUND_GREEN, 80*25, 0h, NULL invoke GetTickCount ;первое случайное число) or eax, 1b ;обязательно не ноль, поэтому включаем первый бит mov dTmp, eax NextLine: mov eax, dTmp mov ecx, 20d mov ebx, offset sLine NextChar: xor edx, edx ;Здесь генерируется случайное 32-х битное число, imul eax, [dMultiplier] idiv [dDivider] mov eax, edx mov [ebx], edx ;помещаем это число в буфер, add ebx, 4h ;т.е. 4 случайных символа loop NextChar mov dTmp, eax ;пишем сгенерированную строку invoke WriteConsoleOutputCharacter, hStdout, offset sLine, 80d, 00000000h, NULL ;!-------------------------------------------------------------------- -----------! ;вот здесь должна читаться первая строка в буфер, но почему-то происходит ошибка ;№12 - что-то вроде "нет доступа", хотя по тому, что написано в SDK, GetStdHandle даёт ;необходимые права invoke ReadConsoleOutputCharacter, hStdout, offset sTmpLine, 80d, 00000000h, NULL cmp eax, 0 je Error invoke WriteConsoleOutputCharacter, hStdout, offset sTmpLine, 80d, 00010000h, NULL jmp NextLine Error: invoke GetLastError mov DWORD PTR [sTmpLine], eax mov dword ptr sTmpLine, eax invoke WriteConsoleOutputCharacter, hStdout, offset sTmpLine, 4d, 00010000h, NULL invoke Sleep, 9000d invoke ExitProcess, NULL Main ENDP end Main
invoke ReadConsoleOutputCharacter, [hStdout], sTmpLine, 80d, 00000000h, pReadNumber;NULL pReadNumber dd ? это для фасма. вообщем посл. параметр - адрес для записи считанных количества байт
Сделал так: Код (Text): dReadNumber dd 0 pReadNumber dd offset dReadNumber ... invoke ReadConsoleOutputCharacter, hStdout, offset sTmpLine, 80d, 00000000h, pReadNumber Как ни странно, всё заработало. Я почему-то думал, что там может NULL стоять. А вообще бред... ведь с WriteConsoleOutputCharacter и NULL прокатило...
пересылки может и не те, но логика думаю понятна ; ReadConsoleOutputCharacter ; esi - pReadNumber ... 7C8728DB 890E MOV [DWORD ESI],ECX ... 7C8728F8 F3:A5 REP MOVS [DWORD ES:EDI],[DWORD ESI] ... ; WriteConsoleOutputCharacter ; edx - pWriteNumber ... 7C872A9F F3:A4 REP MOVS [BYTE ES:EDI],[BYTE ESI] ... 7C872AD4 890A MOV [DWORD EDX],ECX ...