i just want to make sure that i got that right.
when i use the IN and OUT instructions in x86.
the CPU sends the port address to the right I/O controller, how does it know which one is the right one ? it knows by looking up the I/O address space, which basically contain a range of port addresses that correspond to an I/O controller.
so let's say the port addresses 0x1000-0x2000 are for the "disk controller"
and the port address 0x3000-0x4000 are for "network controller"
if i send the port address 0x1003 then the cpu will send the port address to the "disk controller".
then the I/O controller receives that port address it then looks up it's internal mapping table in it's memory to determine what register(could also be a memory) of the I/O device is associated with that port address.
then it request to read or write(depends on the instruction) to one of these I/O device registers.
if i send the port address 0x1003 then the cpu will send the port address to the "disk controller".
Your idea how in
and out
work is not completely correct:
I don't know about modern CPUs, but using a simpler CPU (such as the 80386) in
and out
are variants of the mov
instruction accessing different addresses:
If you see the M/IO
pin just as an additional address wire, addresses are 33-bit values, not 32-bit values.
The instruction out dx, al
does exactly the same as a mov [edx], al
instruction with only one difference: out dx, al
writes to the (33-bit) address [0x100000000+dx]
while mov [edx], al
writes to the address [edx]
.
Now what does the CPU do in this case?
The CPU uses 33 wires (the address bus) to send the address and 8 wires (the data bus) to send the value of al
. It uses additional wires to send the information that some 8-bit value is being written.
There is some circuit outside the CPU that checks which address is which device:
This circuit "knows" that addresses 0...0x9FFFF
are RAM and when you write to one of these addresses (e.g. you write to address 0x1234
using mov [0x1234],al
), the circuit sends an electrical signal to the RAM.
If you write to address 0x100001234
(e.g. using out dx, al
with dx=0x1234
), the circuit sends some signal to the disk controller (in your example).
Let's say the disk controller uses only addresses 0x1000...0x10FF
(actually: 0x100001000...0x1000010FF
).
In this case, the disk controller will typically only use the low 8 bits of the address and ignore the other address bits. So if you write to address dx=0x11FF
, this has the same effect as writing to address dx=0x10FF
.
In this case, only 8 of the 33 signals holding the address coming from the CPU need to be connected to the disk controller.
The disk controller receives the following signals:
al
(from the CPU)