Привет, у меня снова есть проблема, я пытаюсь написать ядро с языком сборки GNU, но у меня есть некоторые проблемы. Мой файл ядра versuch.c
выглядеть так:ядро в c встроенной сборке
void kprintf(char hello[])
{
/*char* video=(char*)0xb8000;
for(int i=0;hello[i]!='\0';i++)
{
video[i*2]=hello[i];
video[i*2+1]=0x06;
}*/
asm("mov %0,%%si"::""(hello));
//asm("mov 'a',%al;");
asm("call Schreibe;"
"Schreibe:;"
"lodsb;"
"cmp $0x00,%al;"
"je Schreibeende;"
"mov $0x0e,%ah;"
"mov $0x00,%bh;"
"int $0x10;"
"jmp Schreibe;"
"Schreibeende:;"
"ret");
}
void main()
{
asm("jmp 0x10000");
char hello[]="hallo";
kprintf(hello);
asm(".rept 512;"
" hlt ;"
".endr");
}`
и мой Загрузчик bootloader.asm
:
org 0x7c00
bits 16
section .text
xor ax,ax
mov ss,ax
xor sp,sp
;xor ax,ax
;mov es,ax
;mov ds,ax
mov [bootdrive],dl
mov bh,0
mov bp,zeichen
mov ah,13h
mov bl,06h
mov al,1
mov cx,6
mov dh,010h
mov dl,01h
int 10h
load:
mov dl,[bootdrive]
xor ah,ah
int 13h
jc load
load2:
mov ax,0x1000
mov es,ax
xor bx,bx
mov ah,2
mov al,1
mov cx,2
xor dh,dh
mov dl,[bootdrive]
int 13h
jc load2
mov ax,0
mov es,ax
mov bh,0
mov bp,zeichen3
mov ah,13h
mov bl,06h
mov al,1
mov cx,13
mov dh,010h
mov dl,01h
int 10h
mov ax,0x1000
mov es,ax
mov ds,ax
jmp 0x1000:0x000
zeichen db 'hello2'
zeichen3 db 'soweit so gut'
bootdrive db 0
times 510 - ($-$$) hlt
dw 0xaa55
, когда я использую команды: gcc -c versuch.c
objcopy -O binary versuch.o versuch.bin
cat bootloader.bin versuch.bin>myOS.bin
qemu-system-i386 myOS.bin
вы можете увидеть, что она проходит через загрузчик до конца распечатывает «soweit so gut», но он не отображает versuch.c (ядро) текст «hallo». Может, кто-то знает, что я сделал не так здесь!
Дело в том, что код ядра я был до того, который был лишь немного изменен на код выше, по крайней мере распечатал символ после «soweit так кишка», который показывает, что код ядра был каким-то образом выполняется и
mov $0xe,%ah
mov $0x0,%bh
int $0x10
был запущен. Но когда я смотрю на hexcode из myOS.bin Теперь с помощью objdump -Mi8086 -mi386 -bbinary -D myOS.bin
я получаю:
28: b8 00 10 8e c0 mov $0xc08e1000,%eax
2d: 31 db xor %ebx,%ebx
2f: b4 02 mov $0x2,%ah
31: b0 01 mov $0x1,%al
33: b9 02 00 30 f6 mov $0xf6300002,%ecx
38: 8a 16 mov (%esi),%dl
3a: 76 7c jbe 0xb8
3c: cd 13 int $0x13
который является mov ah,0x1000
xor bx,bx
диск чтения часть загрузчика и
60: e9 9d 83 68 65 jmp 0x65688402
, который является частью jmp 0x10000
и
27d: b4 0e mov $0xe,%ah
27f: b7 00 mov $0x0,%bh
281: cd 10 int $0x10
, который является частью записи, поэтому каким-то образом он должен перегружать часть записи, но она находится в файле myOS.bin. И, как я сказал, когда мой код немного отличался от строки, он что-то потушил! У вас есть совет, что я мог бы изменить?
Недавно я изменил код ядра versuch.c, а команда и код загрузчика остались прежними.
код ядра (versuch.c):
void kprintf()
{
char* video=(char*)0xb8000;
for(int i=0;video[i]!=0;i++)
{
video[i*2]=0x00;
video[i*2+1]=0x06;
}
}
void main()
{
asm("jmp 0x10000");
asm("mov $0x1000,%eax;"
"mov %eax,%es;"
"mov %eax,%ds");
asm("mov $0x0e,%ah;"
"mov $0x00,%bh;"
"mov 'Q',%al;"
"int $0x10");
asm(".rept 512;"
" hlt ;"
".endr");
}
теперь, кажется, чтобы переключиться в режим видео показывает мигающий курсор, но это не распечатать «Q».
я наконец-то напечатать письмо со следующим кодом ядра: versuch.c:
void kprintf()
{
char* video=(char*)0xb8000;
for(int i=0;video[i]!=0;i++)
{
video[i*2]=0x00;
video[i*2+1]=0x06;
}
}
void main()
{
asm("jmp 0x10000");
asm("mov $0x1000,%eax;"
"mov %eax,%es;"
"mov %eax,%ds");
asm("mov $0x0e,%ah");
asm("mov $0x00,%bh");
asm("mov %0,%%al":: "" ('T'));
asm("int $0x10");
asm(".rept 512;"
" hlt ;"
".endr");
}
но когда я добавить еще одну функцию его снова не работает, что очень странно.
Мой новый код ядра выглядит следующим образом:
asm("jmp main");
void main()
{
char* video=(char*)0xb000;
for(int i=0;video[i]!=0;i++)
video[i]=0x07;
asm("mov $0x1000,%eax;"
"mov %eax,%es;"
"mov %eax,%ds");
char string[]="hall0";
//kprintf(string);
for(int i=0;i<5;i++)
{
asm("mov $0x0e,%ah");
asm("mov $0x00,%bh");
asm("mov %0,%%al":: "" ('a'));
asm("int $0x10");
}
asm(".rept 512;"
" hlt ;"
".endr");
}
я использовал следующие команды: gcc kernel.c -m16 -c kernel.o -nostdlib -ffreestanding
ld -melf_i386 kernel.o -o versuch.elf
и я использую Mint Linux 64-битной машине, и я получаю сообщение об ошибке: no eh_frame_hdr_table will be created
Комментарии для расширенного обсуждения; этот разговор был [перемещен в чат] (http://chat.stackoverflow.com/rooms/130996/discussion-on-question-by-albert-kernel-in-c-inline-assembly). – Flexo