我在Real Mode下编写C程序。该程序将加载到0x2000:0x0000
地址并运行。 DS
注册等于CS
,即0x2000
。我也在调试bochs。
我的目标是在屏幕上打印一些文字。所以我需要内联汇编(对于BIOS INT 10h
)。
这是我的测试文件:
asm("jmp _main");
void putchar(c) char c;
{
asm("mov ah, 0x0e");
asm("mov al, c");
asm("xor bx, bx");
asm("int 0x10");
}
void main ()
{
asm("push cs");
asm("pop ds");
putchar('A');
for(;;);
}
当我用这个命令编译它时......
bcc -W -0 -c test.c -o test.obj
......它在工作。但是当我试图将它与...链接时
ld86 -d isimsiz.obj -o kernel.bin
...它给了我这个错误:
undefined symbol: c
为什么会这样?如何在BCC在线组装下使用C变量?
如果你知道一个关于BCC的好教程,请留下链接。我无法在互联网上找到它:(
提前致谢。
PS:以下是相应compiler BCC和linker LD86的手册页。
答案 0 :(得分:6)
bcc不支持引用C变量。您需要在汇编中编写整个函数:
__FIRST_ARG_IN_AX__
您可能还想检查是否定义了void putchar(c)
{
#asm
mov ah, 0x0e
#if !__FIST_ARG_IN_AX__
mov bx, sp
mov al, [bx+2]
#endif
xor bx, bx
int 0x10
#endasm
}
:
int
请注意,在K& R风格的函数中,函数参数的类型不能比void putchar(c) char c;
窄,因此虽然putchar
在语法上是正确的,但您不能这样做。顺便说一句,这就是为什么libc函数int
采用unsigned equipment;
int has_floppy() {
#asm
int 0x11 ! get BIOS equipment list
mov _equipment,ax
#endasm
return (_equipment & 1);
}
}
类型的参数。
如果您确实需要使用变量,请考虑使用全局变量:
"t"
您可以查看dev86 libc中有关内联汇编的示例。