作为编写操作系统的一部分,我正在实现中断处理和I / O函数inb
和outb
。
我必须学习在GCC中编写内联汇编并在线阅读很多内容。根据我的理解,我编写了自己的代码。与此同时,我查看了Linux /usr/include/sys/io.h
中函数的实现。这就是outb
:
static __inline void
outb (unsigned char __value, unsigned short int __port)
{
__asm__ __volatile__ ("outb %b0,%w1": :"a" (__value), "Nd" (__port));
}
以下是我的问题:
无符号8位整数常量(用于输入和输出指令)。
但是__port
unsigned short int
是__port
我认为是16位。那么如何确定16位的哪一部分用于内联汇编呢?
这是我对其工作原理的理解 - __value
的值将直接用于(因为" N")作为常量来代替%w1。 eax
的值会复制到__port
。 %bo由%al替换。然后执行指令。这是对的吗?
如何确定" N"或" d"用于第二个操作数?是否有一些偏好顺序?
如果我不使用" N"它会有什么不同? ?不会简单地使用" d"更好,因为那是16位?
如果我省略了" N",那么edx
的值被复制到edx
然后%w1被{{1}替换是正确的}?
答案 0 :(得分:2)
我可能错了,但我的理解是"Nd"
表示在编译器的偏好下使用N
或d
。如果未知该值是一个适合8位的常量,则N
不可满足,因此编译器别无选择,只能使用d
。但是当该值是编译时常量并且其值适合8位时,使用8位立即数比浪费寄存器更可取。