As part of writing my OS, I am implementing interrupt handling and the I/O functions inb
and outb
.
I had to learn writing inline assembly in GCC and read up a lot about it online. Based on my understanding, I wrote my own code. Meanwhile, I looked up Linux's implementation of the functions from /usr/include/sys/io.h
. This is what it is like for outb
:
static __inline void
outb (unsigned char __value, unsigned short int __port)
{
__asm__ __volatile__ ("outb %b0,%w1": :"a" (__value), "Nd" (__port));
}
Here are my questions:
Unsigned 8-bit integer constant (for in and out instructions).
But here __port
is unsigned short int
which I believe would be 16 bits. So how is it decided which portion of the 16 bits is used in the inline assembly ?
This is my understanding of how this works - value of __port
will be used directly (because of the "N") as a constant in place of %w1. Value of __value
is copied to eax
. %bo is replaced by %al. Then the instruction is executed. Is this correct ?
How is it decided which of "N" or "d" to use for the second operand ? Is there some preference order ?
What difference does it make if I don't use "N" ? Wouldn't simply using "d" be better, since that is 16 bits ?
If I omitted the "N", then is it correct that value of __port
is copied to edx
and then %w1 is replaced by edx
?
I may be mistaken, but my understanding is that "Nd"
means use either N
or d
, at the compiler's preference. If the value is not known to be a constant that fits in 8 bits, then N
is not satisfiable, so the compiler has no choice but to use d
. But when the value is a compile-time constant and its value fits in 8 bits, using an 8-bit immediate is preferable to wasting a register.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.