2016-09-17 255 views
4

我在实模式下编写C程序。该程序将被加载到0x2000:0x0000地址并运行。 DS寄存器等于CS,即0x2000。另外我正在用bochs进行调试。BCC中的内联汇编(Bruce's C编译器) - 如何使用C变量?

我的目标是在屏幕上打印一些文字。所以我需要内联汇编(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 BCClinker LD86的手册页

+0

另外我忘了提及。如果你知道有关BCC的好教程,请留下链接。我无法在互联网上找到:(在此先感谢.. –

+0

与'putchar'在同一行上声明的'char c;'和无类型变量'c'是什么?应该(除非我错误的,它使用的是非标准的语法)'void putchar(char c)' – enhzflep

+1

@enhzlep BCC使用K&R语法,因此参数是正确的 –

回答

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接受类型为int的参数。

如果你确实需要使用变量,可以考虑使用一个全局变量:

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

    return (_equipment & 1); 
} 
} 

你可以看一下在dev86 libc有关在BCC联汇编的例子。

+0

非常感谢。你知道关于K&R语法的教程吗?也许是一个链接? –

+1

@ B.Kaan获取第一版K&R。或者阅读C标准。 – fuz

+0

我会记住这一点。 –