Я только начал изучать некоторые сборки x86 на win32, и я использовал masm в Visual Studio 2008, используя пользовательское правило сборки, которое поставляется с ide для файлов .asm. Я пытался использовать прерывание DOS для печати на консоль, но вместо этого я получаю сообщение: «Необработанное исключение в 0x00401004 в ASMTest.exe: 0xC0000005: Место чтения нарушения доступа 0xffffffff». на 8-й строке. Я пытаюсь вывести один символ ascii 'A' (41h). Вот код masm:
.386
.MODEL flat, stdcall
.CODE
start:
mov dl, 41h
mov ah, 2
int 21h
ret
end start
Когда я использую debug.exe и использую команду 'a' для ввода всех инструкций .CODE и запускаю ее ('g'), она работает нормально.
Может ли кто-нибудь объяснить мне, как правильно использовать прерывание DOS? Спасибо!
РЕДАКТИРОВАТЬ: при программировании на win32, Манагу прав, что вы должны использовать вызов Windows API, как WriteConsoleA, вместо использования прерывания DOS. Этот был полезным ресурсом. В случае, если кто-то ищет код для этого (как я), вот он:
.386
.MODEL flat, stdcall
; Windows API prototypes
GetStdHandle proto :dword
WriteConsoleA proto :dword, :dword, :dword, :dword, :dword
ExitProcess proto :dword
STD_OUTPUT_HANDLE equ -11
.DATA
HelloWorldString db "hello, world", 10, 0
.CODE
strlen proc asciiData:dword
; EAX used as count, EBX as ascii char pointer, EDX (DL) as ascii char
mov eax, -1
mov ebx, asciiData
mov edx, 0
BeginLoop:
inc eax ; ++count (init is -1)
mov dl, [ebx] ; *dl = *asciiptr
inc ebx ; ++asciiptr
cmp dl, 0 ; if (*dl == '\0')
jne BeginLoop ; Goto the beginning of loop
ret
strlen endp
main proc
invoke GetStdHandle, STD_OUTPUT_HANDLE
mov ecx, eax
invoke strlen, addr HelloWorldString
invoke WriteConsoleA, ecx, addr HelloWorldString, eax, 0, 0
ret
main endp
end
(установить точку входа на главную)