I'm writing a C program under Real Mode. The program will be loaded to 0x2000:0x0000
address and run. DS
register equals to CS
, which is 0x2000
. Also I'm debugging with bochs.
My goal is to print some text on the screen. So that I need inline assembly (for BIOS INT 10h
).
Here is my test file:
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(;;);
}
When I compiled it with this command...
bcc -W -0 -c test.c -o test.obj
...it's working. But when I'm trying to link it with...
ld86 -d isimsiz.obj -o kernel.bin
...it gave me this error:
undefined symbol: c
Why is this happening? How can I use C variables under BCC In-Line Assembly?
If you know a good tutorial about BCC, please leave a link. I couldn't find it on the internet :(
Thanks in advance.
PS: Here are the man pages of the respective compiler BCC and linker LD86.
bcc doesn't support referring to C variables. You need to write the whole function in assembly:
void putchar(c)
{
#asm
mov ah, 0x0e
mov bx, sp
mov al, [bx+2]
xor bx, bx
int 0x10
#endasm
}
You might also want to check if __FIRST_ARG_IN_AX__
is defined:
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
}
Note that in K&R-style functions, function parameters can't have types narrower than int
, so while void putchar(c) char c;
is syntactically correct, you can't do that. Incidentally, this is why the libc function putchar
takes an argument of type int
.
If you really need to use variables, consider using a global variable:
unsigned equipment;
int has_floppy() {
#asm
int 0x11 ! get BIOS equipment list
mov _equipment,ax
#endasm
return (_equipment & 1);
}
}
You can look at the dev86 libc for examples on inline assembly in bcc.