Linux bootc.c中的GCC内联汇编:汇编器消息:错误:表达式后的垃圾'int 0x10h'

问题描述 投票:0回答:1

我正在尝试通过gcc编译c文件并获取错误

gcc -m32 -c bootc.c -o bootc.o
bootc.c: Assembler messages:
bootc.c:5: Error: junk `int 0x10h' after expression   

void kmain(void){
    asm(
        "mov %al, 'H'"
        "int 0x10h"
    );
}
gcc assembly
1个回答
3
投票

GCC中的内联汇编是普通的文字字符串,遵循C或C ++中的常规规则(无论您编程什么)。

这意味着相邻的文字字符串只有空格或它们之间的注释将被连接成单个字符串。

你的想法是什么

asm(
    "mov %al, 'H'"
    "int 0x10h"
);

从编译器的角度来看确实如此

asm(
    "mov %al, 'H' int 0x10h"
);

以上不是有效的指示。

这就是为什么,如果你看一下GCC内联汇编的许多例子,每个装配线后都需要换行。如在

// also converted to Extended Asm syntax to fix other problems
asm(
    "mov $'H', %%al\n"  // Note newline here at the end
    "int $0x10"        // gas doesn't understand trailing-h suffix, only 0x for hex
    : // no outputs
    : // no inputs
    : "ax"  // tell the compiler we clobber AX
     // FIXME: also tell the compiler about any other registers this uses
);

文字字符串仍将连接在一起,但现在汇编程序的指令之间有一个换行符来区分它们。使用\n\t是很常见的,因此编译器的asm输出可以正常读取和缩进。


在相关的说明中,您真的应该了解有关the AT&T/GAS assembly syntax的更多信息,因为您的代码还存在其他问题。例如,汇编代码中的数字文字需要以$为前缀;并且十六进制数字没有十六进制后缀,只有普通的0x前缀(使用前缀和后缀h是多余的)。

另请注意,AT&T语法的目标是最后一个,因此使用'H'将立即值mov $'H', %al移动到AL。

不要忘记根据https://en.wikipedia.org/wiki/INT_10H将AH设置为功能代码。编译器可以用AH做任何想做的事情。

© www.soinside.com 2019 - 2024. All rights reserved.