我正在编写一个内联汇编代码来读取实时时钟。我正在加载要读取的寄存器号码(4)' dl'并将其加载到端口0x70。我试图将此寄存器值(4)读入al。有关详情,请访问RTC
asm(
"mov $4, %%dl;"
"out 0x70, %%dl;"
"in %%al, 0x71;"
:
:
:"%al","%dl"
);
我在编译包含此代码的c文件时收到以下错误消息。
汇编程序消息:
错误:' out'
的操作数大小不匹配错误:`in'
的操作数大小不匹配
汇编程序版本:GNU汇编程序版本2.26.1(x86_64-linux-gnu)使用BFD版本(GNU Binutils for Ubuntu)2.26.1
有人可以指出这个问题吗?
答案 0 :(得分:4)
有很多问题。首先,in
和out
只能在A寄存器(al
,ax
,eax
,rax
)上运行。其次,操作数顺序是错误的,第三,immediates必须以AT& T语法中的$
作为前缀。在普通程序集中,您的代码应如下所示:
mov $4,%al
out %al,$0x70
in $0x71,%al
所以你的校正装配将是
asm(
"movb $4, %%al;"
"outb %%al, $0x70;"
"inb $0x71, %%al;"
:
:
:"%al"
);
请注意,我添加了显式大小后缀以帮助clang汇编此代码。我建议您进一步更改此代码以使用正确的扩展内联汇编:
unsigned char result;
volatile asm("outb %1,$0x70; inb $0x71, %0" : "=a"(result) : "a"((char)4));
这可以使gcc生成稍好的代码。例如,它允许gcc内联此代码。
此外,您可以考虑使用inb()
中的outb()
和<sys/io.h>
宏来完全避免内联汇编。这通常是一件非常好的事情。