I'm disassembling a 16-bit DOS executable, and looking at the following three instructions:

mov dx,0x3ce
mov ax,0xff08
out dx,ax

I know it writes the value 0xff08 to I/O port 0x3ce. I also know that port 0x3ce is the "Graphics 1 & 2 Address" register on an IBM EGA card. Problem is, according to the manual, this port should take a byte value, not a word.

What I'm guessing is happening is that the word 0xff08 is taken as two different bytes, where one byte ends up in the specified register and the other goes to an adjacent one. Or maybe the offending byte gets thrown out? Either way it's a guess, as I can't seem to find much info about this specific behavior.

I don't have a good intuitive sense about which direction the I/O address space flows, or how the little-endian storage of the word may come into play. After this snippet executes, which ports got which bytes?

1 Answer 1


Port I/O works similar to memory I/O, so the low byte (08) will be written to the port 3CE and the high byte (0xFF) to the port 3CF.

Example from Use of bitplanes in mode 12h:

The index port of the Graphics Controller (part of the VGA interface) is at $3CE. The data port is at (index+1), so $3CF. If we want to write a 4 to index 2, we do: Port[$3CE]:=2; { index } Port[$3CF]:=4; { data } But there is a way to do it with one Port[]. There's also a PortW[] 'array', and if the addressed port isn't a 16-bit one, it sends the lo byte to address, and the high byte to address+1. Just what we need. The example becomes: PortW[$3CE]:=$0402; { index in low byte, data in high byte }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.