Я пишу маленькое «ядро», которое отображает «Hello world!»на экране.У меня есть работающая функция putc (put char), поэтому я могу сделать это (и я сделал это) с 12 вызовами функций putc, но я хочу сделать это с помощью функции put (put string), и я хочу написать ее на C ++.Я знаю, что могу сделать это на C, но в будущем мне понадобится C с C ++ связыванием ... Так почему бы не сделать это прямо сейчас?
Вот мой код kernel.c:
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(;;);
}
Я изменил код put.cpp, чтобы он отображал на экране первую букву строки ... но это не так ...
put.cpp:
extern "C" void putc(char, char);
extern "C"
{
void puts(char *s, char color)
{
putc(*s, 7);
}
}
Эта функция очищает VGA 80x25 с размером 4000 байтов
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:
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
После генерации iso, запустив его с qemu-system-x86_64-hdd kernel.iso, он отображает странные символы (каждый раз это одно и то же) и Hello world!Конечно, после размещения этой функции в файле kernel.c она отображает мир HHello!
Интересно то, что после замены gcc на clang ++ (для put.cpp) он отображает еще один странный символ (также каждый раз такой же)
После замены содержимого функции put () на putc ('a', 7);он отображает эту букву правильно, поэтому похоже, что существует проблема с передачей аргументов между C и C +++, а не C ++ и сборкой, но, возможно, я ошибаюсь ...