嗯,这显然是一个初学者的问题,但这是我第一次尝试制作操作系统C
(实际上,我几乎完全陌生C
..我已经习惯了asm
)那么,为什么这实际上是无效的呢?据我所知,一个pointer
in C
只是一个uint16_t
用于指向内存中的某个区域,右(或uint32_t
这就是为什么它不起作用)?
我制作了以下内核(“我已经制作了引导加载程序和所有组件以加载生成的 KERNEL.BIN 文件):
kernel.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: Error: operand type mismatch for '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 指令。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)