2
votes

I have some C code that uses the inb instruction in inline assembly. I heard that inb takes operands that have a size of 8-bits. AL and DL are 8 bits, so why won't this work?

__asm__ __volatile__("inb %al, %dl");

It says "Operand type mismatch for in". If it matters, I have the ".code16gcc" at the top. All help is appreciated.

1
Parameters need to be changed around as ATT syntax has src as first operand and dest as the second. As well the port register has to be DX not DL.As well you need to understand that if you alter a register like AL you need to tell GCC that you clobbered EAX. You also have to have some type of constraint to properly move it somewhere. Inline assembly is very hard to get right and that code project tutorial has set you down a path of pain because they didn't understand that either.Michael Petch
A proper way to do a function like this would be uint8_t inb(uint16_t port) { uint8_t ret; asm volatile ("inb %1, %0" : "=a" (ret) : "dN" (port)); return ret; } . I usually mark such a function as static inline and place it in header file.Michael Petch

1 Answers

1
votes

Two things: In AT&T-style assembly, the destination operand is last, and the port number is 16 bits even when the data is 8 bits. So:

    inb %dx, %al