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

时间:2018-09-10 19:17:20

标签: gcc assembly

我正在尝试通过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"
    );
}

1 个答案:

答案 0 :(得分: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进行任何所需的操作。