0

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.

Pouria
  • 49
  • 8
  • 7
    In protected mode ports are privileged. You either need permissions or have to be in kernel mode. – Jester May 20 '21 at 14:59

1 Answers1

3

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.

vitsoft
  • 5,515
  • 1
  • 18
  • 31
  • You can have IOPL=0 without CPL=0 (ring 0). e.g. Linux's [`iopl` system call](https://man7.org/linux/man-pages/man2/iopl.2.html). x86 also has hardware support for a per-port access permission map that lets the kernel grant user-space permission for some specific low port numbers to a user-space process (Linux [`ioperm` system call](https://man7.org/linux/man-pages/man2/ioperm.2.html)). (I assume that's why Jester didn't try to be specific about what permissions are required for `in` in a comment, because it's non-trivial to describe all the ways). – Peter Cordes May 20 '21 at 18:04
  • Agreed that doing any of this for a delay timer is crazy in user-space under a multi-tasking OS, though! – Peter Cordes May 20 '21 at 18:04
  • 1
    Found more detail about how ioperm works: there's a permission bitmap in the TSS: [How does Linux handles the I/O Permission Bitmap in the TSS structure?](https://stackoverflow.com/q/55501443) – Peter Cordes May 20 '21 at 18:07