I am trying to write a delay timer using port 61H (PB4) and using MASM
run it on a Windows XP on virtual machine. However, when the code runs the IN
instruction, it crashes the program, no matter which port is called.
.386
.model flat,stdcall
include C:\masm32\include\windows.inc
include C:\masm32\include\masm32.inc
include C:\masm32\include\msvcrt.inc
include C:\masm32\include\kernel32.inc
includelib C:\masm32\lib\masm32.lib
includelib C:\masm32\lib\msvcrt.lib
includelib C:\masm32\lib\kernel32.lib
.data
msg1 db "text 1 ", 0
msg2 db "text 2", 0
msg3 db "text 2", 0
.code
start proc
invoke crt_printf, offset msg1
push cx
call waitf
pop cx
invoke crt_printf, offset msg2
invoke crt_scanf, offset msg3
invoke ExitProcess,0
start endp
waitf proc near
mov cx, 33144
push ax
waitf1:
in al, 61h
and al, 10h
cmp al, ah
je waitf1
mov ah, al
loop waitf1
pop ax
ret
waitf endp
end start
I can not understand why the computer can not get data from the port 61h.
Computer can get data from I/O port but only if it runs in real mode or in ring 0, which is reserved for kernel and device drivers. In native DOS you can read whichever I/O port you like, and some well-known ports can be read/written even when the realmode program runs in simulator (NTVDM, DosBox).
But as you have chosen Windows protected-mode executable, this won't work.
Invoke WinAPI function Sleep(dwMilliseconds) instead.