IN 和 OUT 指令的 GNU 汇编程序语法
GNU assembler syntax for IN and OUT instructions
我正在编写内联汇编代码来读取实时时钟。我正在将要读取的寄存器号 (4) 加载到 'dl' 并将其加载到端口 0x70。我正在尝试将此寄存器值(4)读入 al。更多信息 - RTC
asm(
"mov , %%dl;"
"out 0x70, %%dl;"
"in %%al, 0x71;"
:
:
:"%al","%dl"
);
我在编译包含此代码的 c 文件时收到以下错误消息。
Assembler messages:
Error: operand size mismatch for 'out'
Error: operand size mismatch for `in'
汇编器版本:GNU 汇编器版本 2.26.1 (x86_64-linux-gnu) 使用 BFD 版本 (GNU Binutils for Ubuntu) 2.26.1
有人可以指出问题吗?
有很多问题。首先,in
和out
都只能对A寄存器进行操作(al
、ax
、eax
、rax
)。第二,操作数顺序错误,第三,在 AT&T 语法中,立即数必须以 $
为前缀。在普通汇编中,您的代码应如下所示:
mov ,%al
out %al,[=10=]x70
in [=10=]x71,%al
因此您更正后的程序集将是
asm(
"movb , %%al;"
"outb %%al, [=11=]x70;"
"inb [=11=]x71, %%al;"
:
:
:"%al"
);
请注意,我添加了明确的大小后缀以帮助 clang assemble 这段代码。我建议您进一步修改此代码以使用正确的扩展内联汇编:
unsigned char result;
volatile asm("outb %1,[=12=]x70; inb [=12=]x71, %0" : "=a"(result) : "a"((char)4));
这可以使 gcc 生成稍微更好的代码。例如,它允许 gcc 内联这段代码。
此外,您可以考虑使用 <sys/io.h>
中的 inb()
和 outb()
宏来完全避免内联汇编。这通常是一件非常好的事情。
我正在编写内联汇编代码来读取实时时钟。我正在将要读取的寄存器号 (4) 加载到 'dl' 并将其加载到端口 0x70。我正在尝试将此寄存器值(4)读入 al。更多信息 - RTC
asm(
"mov , %%dl;"
"out 0x70, %%dl;"
"in %%al, 0x71;"
:
:
:"%al","%dl"
);
我在编译包含此代码的 c 文件时收到以下错误消息。
Assembler messages:
Error: operand size mismatch for 'out'
Error: operand size mismatch for `in'
汇编器版本:GNU 汇编器版本 2.26.1 (x86_64-linux-gnu) 使用 BFD 版本 (GNU Binutils for Ubuntu) 2.26.1
有人可以指出问题吗?
有很多问题。首先,in
和out
都只能对A寄存器进行操作(al
、ax
、eax
、rax
)。第二,操作数顺序错误,第三,在 AT&T 语法中,立即数必须以 $
为前缀。在普通汇编中,您的代码应如下所示:
mov ,%al
out %al,[=10=]x70
in [=10=]x71,%al
因此您更正后的程序集将是
asm(
"movb , %%al;"
"outb %%al, [=11=]x70;"
"inb [=11=]x71, %%al;"
:
:
:"%al"
);
请注意,我添加了明确的大小后缀以帮助 clang assemble 这段代码。我建议您进一步修改此代码以使用正确的扩展内联汇编:
unsigned char result;
volatile asm("outb %1,[=12=]x70; inb [=12=]x71, %0" : "=a"(result) : "a"((char)4));
这可以使 gcc 生成稍微更好的代码。例如,它允许 gcc 内联这段代码。
此外,您可以考虑使用 <sys/io.h>
中的 inb()
和 outb()
宏来完全避免内联汇编。这通常是一件非常好的事情。