Gcc mov的指令后缀无效?

Gcc mov的指令后缀无效?,gcc,x86,inline-assembly,gnu-assembler,intel-syntax,Gcc,X86,Inline Assembly,Gnu Assembler,Intel Syntax,我有一段内联汇编代码,应该以文本模式打印: void print(){ asm volatile( "mov ax,0xb800\n" "mov ds,ax\n" /*<-as complains about this*/ "movb 0,'A'\n" ); } 顺便说一句,这段代码来自我的操作系统内核,所以我不能使用stdio.h或类似的东西。尽管错误消息中有GCC的行号,但它实

我有一段内联汇编代码,应该以文本模式打印:

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

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

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

我怀疑GAS
。“英特尔语法”模式将文本
0
视为立即数,为了与
mov al保持一致,将0
0
视为源操作数。这当然不能作为目的地

“无效指令后缀”错误消息没有什么意义,不过请注意,英特尔语法不使用操作数大小后缀。(但由于某种原因,
movb[0],“A”被接受。)

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

    mov  byte ptr [0], 'A'
mov byte ptr ds:0,'A'
也可以工作,并且是
objdump-d-Mintel
使用的语法


总是在内存操作数上使用方括号来消除任何歧义是个好主意,特别是对于那些可能习惯于英特尔NASM语法风格的人来说。

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

我怀疑GAS
。“英特尔语法”模式将文本
0
视为立即数,为了与
mov al保持一致,将0
0
视为源操作数。这当然不能作为目的地

“无效指令后缀”错误消息没有什么意义,不过请注意,英特尔语法不使用操作数大小后缀。(但由于某种原因,
movb[0],“A”被接受。)

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

    mov  byte ptr [0], 'A'
mov byte ptr ds:0,'A'
也可以工作,并且是
objdump-d-Mintel
使用的语法


始终在内存操作数上使用方括号是一个好主意,以消除任何歧义,特别是对于那些可能习惯于英特尔NASM语法风格的人来说。

您确定这是正确的汇编语法吗?语法可能因汇编程序而异。我使用英特尔语法,并且已经添加了-masm=Intel。您确定这是正确的汇编语法吗?语法可能因汇编程序而异。我使用英特尔语法,并且我已经添加了-masm=Intel.From:“通常不鼓励使用对英特尔语法的支持,因为它可能与其他汇编程序中的真正英特尔语法有细微的、出人意料的不同。”。有可能将
0
标记视为立即值,即使在该位置不可能这样做,
ds:0
[0]
都会改变其性质。只是猜测,但确实有点道理。@paxdiablo:是的,看起来像是一个即时消息是我猜测它为什么被拒绝的原因,以及我为什么尝试
ds:0
[0]
来看看它们是否有效。大多数人都同意这种观点;使用GNU
.intel_syntax
作为objdump/gdb/gcc asm输出等内容的只读格式,除非您不介意找出如何解决GAS英特尔语法中偶尔出现的设计问题。但是,如果您真的必须使用GNUC扩展内联asm(而不是在NASM中编写独立函数),那么对于个人项目来说,它肯定是一个有效的选项。不过,Glibc和Linux源代码仅使用AT&T。From:“通常不鼓励使用对英特尔语法的支持,因为它可能与其他汇编程序中的真正英特尔语法有微妙而令人惊讶的不同。”。有可能将
0
标记视为立即值,即使在该位置不可能这样做,
ds:0
[0]
都会改变其性质。只是猜测,但确实有点道理。@paxdiablo:是的,看起来像是一个即时消息是我猜测它为什么被拒绝的原因,以及我为什么尝试
ds:0
[0]
来看看它们是否有效。大多数人都同意这种观点;使用GNU
.intel_syntax
作为objdump/gdb/gcc asm输出等内容的只读格式,除非您不介意找出如何解决GAS英特尔语法中偶尔出现的设计问题。但是,如果您真的必须使用GNUC扩展内联asm(而不是在NASM中编写独立函数),那么对于个人项目来说,它肯定是一个有效的选项。不过,Glibc和Linux源代码只使用AT&T。