I'm writing little "kernel" that displays "Hello world!" on the screen. I have working putc (put char) function so I can do it (and I did it) with 12 putc function calls but I want do it with puts (put string) function and I want to write it in C++. I know that I can make it in C but I'll need C with C++ linking in the future... So why not do it right now?
Here is my kernel.c code:
extern void putc(char, char);
extern void puts(char*, char);
extern void clear(void);
void start_kernel(void)
{
clear();
puts("Hello world!", 7);
putc('H', 7);
putc('e', 7);
putc('l', 7);
putc('l', 7);
putc('o', 7);
putc(' ', 7);
putc('w', 7);
putc('o', 7);
putc('r', 7);
putc('l', 7);
putc('d', 7);
putc('!', 7);
for(;;);
}
I changed the puts.cpp code so that it should display the first letter of the string on the screen... but it doesn't...
puts.cpp:
extern "C" void putc(char, char);
extern "C"
{
void puts(char *s, char color)
{
putc(*s, 7);
}
}
This function clears 80x25 VGA buffor it have 4000 bytes size
clear.asm:
BITS 32
GLOBAL clear
clear:
push eax
mov eax, 0xb8000
dec eax
L1:
inc eax
mov byte [eax], 0
cmp eax, 0xb8fa0
jb L1
pop eax
ret
putc.asm:
BITS 32
GLOBAL putc
putc:
push eax
mov eax, 0xb8000
dec eax
L1:
inc eax
cmp byte [eax], 0
jnz L1
mov [eax], edi
mov [eax+1], esi
pop eax
ret
kernel.ld:
OUTPUT_FORMAT("binary")
ENTRY("_start")
SECTIONS {
.text 0x100000 : {
code = . ; _code = . ;
*(.text)
}
.data : {
*(.data)
}
.bss : {
bss = . ; _bss = . ;
*(.bss)
*(.COMMON)
}
end = . ; _end = . ;
}
start.asm:
BITS 64
section .text
EXTERN code,bss,end
mboot:
dd 0x1BADB002
dd 0x10001
dd -(0x1BADB002+0x10001)
dd mboot
dd code
dd bss
dd end
dd _start
GLOBAL _start
_start:
cli
mov esp,kstack+4096
mov ax,0x10
mov ds,ax
mov es,ax
mov fs,ax
mov gs,ax
lgdt [gdt_descr]
jmp .1
.1:
push dword 0
push dword 0
push dword 0
push dword L6
EXTERN start_kernel
push dword start_kernel
ret
L6:
jmp L6
section .bss
kstack: resd 1024
section .data
gdt_descr:
dw 256*8-1
dd _gdt
GLOBAL _gdt
_gdt:
dd 0,0
dd 0x0000FFFF,0x00CF9A00
dd 0x0000FFFF,0x00CF9200
dd 0,0
times 254 dd 0,0
link.bash script:
nasm start.asm -f elf64 -o start.o
nasm putc.asm -f elf64 -o putc.o
nasm clear.asm -f elf64 -o clear.o
gcc puts.cpp -std=c++0x -c -o puts.o
gcc kernel.c -O3 -fomit-frame-pointer -masm=intel -c -o kernel.o
ld -Tkernel.ld -o kernel.bin start.o kernel.o putc.o puts.o clear.o
After generating iso running it with qemu-system-x86_64 -hdd kernel.iso , it displays weird character (each time this same) and Hello world! Of course after placing this function in kernel.c file it displays HHello world!
Interesting thing is that after replacing gcc with clang++ (for puts.cpp) it displays another weird character (also each time this same)
After replacing puts() function content with putc('a', 7); it displays this letter correctly so it looks like there is a problem with passing arguments between C and C+++ not C++ and assembly but maybe I'm wrong...
User contributions licensed under CC BY-SA 3.0