Hallo, ich habe wieder einmal ein Problem Ich versuche, einen Kernel mit der GNU-Assemblersprache zu schreiben, aber ich habe ein paar Probleme. Meine Kernel-Datei versuch.c
sehen wie folgt aus:Kernel in c Inline-Assembly
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");
}`
und mein Bootloader 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
Wenn ich die Befehle: gcc -c versuch.c
objcopy -O binary versuch.o versuch.bin
cat bootloader.bin versuch.bin>myOS.bin
qemu-system-i386 myOS.bin
können Sie sehen, dass es läuft durch der Bootloader bis zum Ende druckt "soweit so gut" aus aber es zeigt nicht den versuch.c (kernel) Text "hallo". Vielleicht weiß jemand, was ich hier falsch gemacht habe!
Die Sache ist die, dass der Kernel-Code i vor dem hatte, war nur leicht ein Zeichen über zumindest ausgedruckt nach „soweit so gut“, um den Code geändert, die zeigt, dass die Code-Kernel irgendwie ausgeführt wurde und
mov $0xe,%ah
mov $0x0,%bh
int $0x10
wurde ausgeführt. Aber wenn ich am hexcode von myOS.bin nun einen Blick über objdump -Mi8086 -mi386 -bbinary -D myOS.bin
i erhalten:
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
, die die mov ah,0x1000
xor bx,bx
Plattenlese Teil des Bootloader ist und
60: e9 9d 83 68 65 jmp 0x65688402
die der jmp 0x10000
Teil ist und
27d: b4 0e mov $0xe,%ah
27f: b7 00 mov $0x0,%bh
281: cd 10 int $0x10
was der schreibende Teil ist, also muss es irgendwie den schreibenden Teil überspringen, aber es ist in der myOS.bin Datei. Und wie gesagt, als mein Code mit der Zeichenkette nur geringfügig anders war, hat er etwas ausgegeben! Hast du einen Ratschlag, was ich hätte ändern können?
Ich habe kürzlich meinen Kernel-Code versuch.c geändert, während der Befehl und der Bootloader-Code unverändert bleiben.
Kernel-Code (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");
}
jetzt scheint es auf den Videomodus zu wechseln ein blinkender Cursor zeigt aber es tut out 'Q' drucken.
Ich habe endlich einen Brief mit folgendem Kernel-Code drucken: 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");
}
aber wenn ich hinzufügen, eine andere Funktion ist es nicht mehr, dass wirklich seltsam arbeiten.
Mein neuer Kernel-Code sieht wie folgt aus:
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");
}
i die folgenden Befehle verwendet: gcc kernel.c -m16 -c kernel.o -nostdlib -ffreestanding
ld -melf_i386 kernel.o -o versuch.elf
und ich bin mit Mint Linux 64-Bit-Maschine und ich bekomme die Fehlermeldung: no eh_frame_hdr_table will be created
Kommentare sind nicht für längere Diskussionen; Diese Konversation wurde [in den Chat verschoben] (http://chat.stackoverflow.com/rooms/130996/discussion-on-question-by-albert-kernel-in-c-inline-assembly). – Flexo