2016-09-17 161 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

我會記住這一點。 –