uint16_t port;
uint8_t value;
...
asm volatile ("outb %1, %0"
:
: "dN" (port), "a" (value)
);
写玩具内核的时候看到要读写端口,接触到了gcc的内联汇编,如上,解释一下
outb %1, %0 表示把%1的内容写到%0对应的端口中去,%0和%1不是立即数的意思,它们代表的是后面的(port)和(value)的值,数字是根据它们的相对排列得来的,所以port是%0,value是%1。也就是说这条指令实际上就是 outb value, port的意思。
对于gcc的这种内联汇编的格式也在这里解释一下,可以看到和传统接触的 "movl %ebx ,%eax"有点点不同,格式是这样的
asm ( assembler template /*指令表达式*/
: output operands /* 输出变量 */
: input operands /* 输入变量 */
: list of clobbered registers /* 变化表 */
);
指令表达式 就是类似与"movl %ebx, %eax"的表达式
输入变量代表的是这个变量在指令表达式中引用的时候作为结果存储输出的地方
输入变量代表的是这个变量在指令表达式中引用的时候作为提供输入的地方
变化表就不在这里细说了,可以参考文末链接中更加系统详细的说明
这里举个例子说明一下输入变量和输出变量
uint16_t port;
uint8_t ret;
....
asm volatile("inb %1, %0"
: "=a" (ret)
: "dN" (port)
);
inb %1, %0 表示从 %1(port)中读取值存放到%0(ret)中去,可以理解成输入变量就是把变量值直接替换到指令中当成个立即数去使用,而输出变量就是把变量的地址替换到指令中当成一个地址去写, "=a"和"dN"是修饰想了解参考文末链接。
参考链接:
GCC-Inline-Assembly-HOWTO:http://blog.csdn.net/iamlbccc/article/details/7212837