4

我正在实模式下编写 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 In-Line Assembly 下使用 C 变量?

如果您知道关于密件抄送的好教程,请留下链接。我在互联网上找不到它:(

提前致谢。

PS:这里是各自编译器 BCC链接器 LD86的手册页。

4

1 回答 1

6

bcc 不支持引用 C 变量。您需要在汇编中编写整个函数:

void putchar(c)
{
#asm
     mov ah, 0x0e
     mov bx, sp
     mov al, [bx+2]
     xor bx, bx
     int 0x10
#endasm
}

您可能还想检查是否__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
}

请注意,在 K&R 风格的函数中,函数参数的类型不能小于int,因此虽然void putchar(c) char c;语法正确,但您不能这样做。顺便说一句,这就是 libc 函数putchar采用 type 参数的原因int

如果确实需要使用变量,请考虑使用全局变量:

unsigned equipment;
int has_floppy() {
#asm
    int 0x11 ! get BIOS equipment list
    mov _equipment,ax
#endasm

    return (_equipment & 1);
}
}

您可以查看dev86 libc以获取有关 bcc 中的内联汇编的示例。

于 2016-09-17T09:43:25.367 回答