OUTSB loads a byte from [DS:SI] or [DS:ESI] and writes
it to the I/O port specified in DX. It then increments or
decrements (depending on the direction flag: increments if the flag
is clear, decrements if it is set) SI or ESI.
The register used is SI if the address size is 16 bits, and
ESI if it is 32 bits. If you need to use an address size not
equal to the current BITS setting, you can use an explicit
a16 or a32 prefix.
The segment register used to load from [SI] or [ESI] can be
overridden by using a segment register name as a prefix (for
example, es outsb).
OUTSW and OUTSD work in the same way, but they output a
word or a doubleword instead of a byte, and increment or decrement
the addressing registers by 2 or 4 instead of 1.
The REP prefix may be used to repeat the instruction CX (or
ECX - again, the address size chooses which) times.