gpt4 book ai didi

c - GCC 裸机内联汇编 SI 寄存器不能很好地处理指针

转载 作者:太空宇宙 更新时间:2023-11-03 23:21:06 25 4
gpt4 key购买 nike

嗯,这显然是一个初学者的问题,但这是我第一次尝试用 C 制作操作系统(实际上,我对 C 几乎完全陌生.. 我已经习惯了 asm) 那么,为什么这到底是无效的呢?据我所知,C 中的pointer 只是一个uint16_t 用于指向内存中的某个区域,对(或 uint32_t 这就是它不起作用的原因)?我制作了以下内核(“我已经制作了一个引导加载程序和所有程序集以加载生成的 KERNEL.BIN 文件):

内核.c

void printf(char *str)
{
__asm__(
"mov si, %0\n"
"pusha\n"
"mov ah, 0x0E\n"
".repeat:\n"
"lodsb\n"
"cmp al, 0\n"
"je .done\n"
"int 0x10\n"
"jmp .repeat\n"
".done:\n"
"popa\n"
:
: "r" (str)
);
return;
}

int main()
{
char *msg = "Hello, world!";
printf(msg);
__asm__("jmp $");
return 0;
}

我使用以下命令编译它kernel.c:

gcc kernel.c -ffreestanding -m32 -std=c99 -g -O0 -masm=intel -o kernel.bin

返回以下错误:

kernel.c:3:错误:“mov”的操作数类型不匹配

为什么可能是这个错误的原因?

最佳答案

正如 Michael Petch 已经解释过的那样,您仅将内联汇编用于 C 中无法完成的绝对最小代码。对于其余部分,可以使用内联汇编,但您必须非常小心地正确设置约束和破坏列表.

总是让 GCC 完成将值传递到正确寄存器中的工作,并且只需指定值应该在哪个寄存器中。

对于你的问题,你可能想做这样的事情

#include <stdint.h>

void print( const char *str )
{
for ( ; *str; str++) {
__asm__ __volatile__("int $0x10" : : "a" ((int16_t)((0x0E << 8) + *str)), "b" ((int16_t)0) : );
}
}

编辑:您的程序集存在问题,您试图在 16 位寄存器中传递指针。这不适用于 32 位代码,因为 32 位也是指针大小。如果你想生成 16 位实模式代码,可以使用 -m16 选项。但这并不能使 GCC 成为真正的 16 位编译器,它有其局限性。本质上,它在代码中发出一个 .code16gcc 指令。

关于c - GCC 裸机内联汇编 SI 寄存器不能很好地处理指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39482526/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com