mov 的无效指令后缀?

invalid instruction suffix for mov?

我有这段内联汇编代码,应该在文本模式下打印 A:

    void print(){
        asm volatile(
            "mov ax,0xb800\n"
            "mov ds,ax\n" /*<-as complains about this*/
            "movb 0,'A'\n"
    ); 
} 

然而,当我尝试使用 gcc(使用 -m32 和 -masm=intel)编译它时:

./source/kernel.c: Assembler messages:
./source/kernel.c:4: Error: invalid instruction suffix for `mov'

顺便说一句,这段代码来自我的操作系统内核,所以我不能使用 stdio.h 或类似的东西。

尽管错误消息中有 GCC 的行编号,但这并不是它实际抱怨的行,而是 movb 商店。您可以通过评论其他说明来测试它。该错误实际上是由汇编程序打印的,编号基于编译器的 .loc 元数据指令,这是一个多行汇编模板,所以我猜很容易出错。

我怀疑 GAS .intel_syntax 模式将文字 0 视为立即数,以与 mov al, 00 作为源操作数保持一致。这当然不能作为目的地。

"invalid instruction suffix" 错误消息没有什么意义,但请注意英特尔语法不使用操作数大小后缀。 (不过出于某种原因 movb [0], 'A' 被接受了。)

而是使用方括号来避免歧义;建议用于 任何 内存操作数,即使地址是符号而不是文字数字。

    mov  byte ptr [0], 'A'

mov byte ptr ds:0, 'A' 也有效,并且是 objdump -d -Mintel 使用的语法。

始终在内存操作数上使用方括号以消除歧义是个好主意,尤其是对于那些可能习惯了 NASM Intel 语法风格的人。