Hi,
ich hoffe es macht nichts, dass ich im Moment zwei Threads hier offen habe.
Die beiden Probleme sind miteinander verwandt.
Ich weiß nicht, ob mein Vorhaben überhaupt funktionieren kann.
Ich programmiere zurzeit ein kleines Betriebssystem. Ich habe eine kernel.asm mit der ich meinen C Kernel aufrufe.
Nun kann ja die Sprache C an sich ziemlich wenig, was bedeutet, dass ich wiederum Assembler brauche. Ich aber kein Freund von inline-assembling und wollte deshalb die Funktionen in externe Dateien speichern, die ich assembliere und dann mit linke. Im Prinzip sieht das so aus:
<linke> kernel.bin kernelASM.elf kernelC.elf read.elf
Die kernel.asm ruft nur den C Kernel auf, sprich
Die kernel.c sieht so aus:
Die read.asm ist
Das Ergebnis des ganzen ist, dass read() übersprungen wird und gleich rebootet wird. Also habe ich die kernel.bin mal disassembliert und erkenne, dass nicht zu "read" gesprungen wird, sondern eine Adresse davor und das ist das "ret" des C Codes, was im Endeffekt bedeutet, dass read() übersprungen wird.
Also habe ich versuch, so zu linken:
<linke> kernel.bin kernelASM.elf read.elf kernelC.elf
was aber darauf hinaus läuft, dass zwar auf die richtige "read" Stelle gesprungen, aber nicht zu "main" gesprungen wird. Die Folge ist, dass das OS hängt.
Ich hoffe ihr versteht das Problem.
Weil ich vermute, dass es am Linker liegt (ld) poste ich hier mal das Linkerscript:
Danke im Voraus und für's bis hierher lesen 
EDIT1:
Assembler ist NASM, C Compiler ist gcc und Linker ist ld.
EDIT2:
Hier das Ergbnis des Disassemblers für beide Fälle:
kernelC.elf vor read.elf
read.elf vor kernelC.elf
EDIT3:
Kompletter Code:
kernel.asm
kernel.c
read.asm
Ich glaube, dass war's erstmal.
ich hoffe es macht nichts, dass ich im Moment zwei Threads hier offen habe.
Die beiden Probleme sind miteinander verwandt.
Ich weiß nicht, ob mein Vorhaben überhaupt funktionieren kann.
Ich programmiere zurzeit ein kleines Betriebssystem. Ich habe eine kernel.asm mit der ich meinen C Kernel aufrufe.
Nun kann ja die Sprache C an sich ziemlich wenig, was bedeutet, dass ich wiederum Assembler brauche. Ich aber kein Freund von inline-assembling und wollte deshalb die Funktionen in externe Dateien speichern, die ich assembliere und dann mit linke. Im Prinzip sieht das so aus:
<linke> kernel.bin kernelASM.elf kernelC.elf read.elf
Die kernel.asm ruft nur den C Kernel auf, sprich
Code:
; ...
extern main
call main
; ...
Die kernel.c sieht so aus:
C:
extern int read();
int main() {
read();
return 0;
}
Die read.asm ist
Code:
global read
read:
mov ah, 0x0
int 0x16
ret
Das Ergebnis des ganzen ist, dass read() übersprungen wird und gleich rebootet wird. Also habe ich die kernel.bin mal disassembliert und erkenne, dass nicht zu "read" gesprungen wird, sondern eine Adresse davor und das ist das "ret" des C Codes, was im Endeffekt bedeutet, dass read() übersprungen wird.
Also habe ich versuch, so zu linken:
<linke> kernel.bin kernelASM.elf read.elf kernelC.elf
was aber darauf hinaus läuft, dass zwar auf die richtige "read" Stelle gesprungen, aber nicht zu "main" gesprungen wird. Die Folge ist, dass das OS hängt.
Ich hoffe ihr versteht das Problem.
Weil ich vermute, dass es am Linker liegt (ld) poste ich hier mal das Linkerscript:
Code:
OUTPUT_FORMAT("binary")
ENTRY(start)
phys = 0x00100000;
SECTIONS
{
.text phys : AT(phys) {
code = .;
*(.text)
*(.rodata)
. = ALIGN(4096);
}
.data : AT(phys + (data - code))
{
data = .;
*(.data)
. = ALIGN(4096);
}
.bss : AT(phys + (bss - code))
{
bss = .;
*(.bss)
. = ALIGN(4096);
}
end = .;
}

EDIT1:
Assembler ist NASM, C Compiler ist gcc und Linker ist ld.
EDIT2:
Hier das Ergbnis des Disassemblers für beide Fälle:
kernelC.elf vor read.elf
Code:
00000000 E80700 call word 0xa
00000003 0000 add [bx+si],al
00000005 EA0000FFFF jmp word 0xffff:0x0
0000000A 0000 add [bx+si],al
0000000C 8D4C24 lea cx,[si+0x24]
0000000F 0483 add al,0x83
00000011 E4F0 in al,0xf0
00000013 FF71FC push word [bx+di-0x4]
00000016 55 push bp
00000017 89E5 mov bp,sp
00000019 51 push cx
0000001A 83EC04 sub sp,byte +0x4
0000001D E80E00 call word 0x2e
00000020 0000 add [bx+si],al
00000022 B80000 mov ax,0x0
00000025 0000 add [bx+si],al
00000027 83C404 add sp,byte +0x4
0000002A 59 pop cx
0000002B 5D pop bp
0000002C 8D61FC lea sp,[bx+di-0x4]
0000002F C3 ret
00000030 B400 mov ah,0x0
00000032 CD16 int 0x16
00000034 B400 mov ah,0x0
00000036 C3 ret
00000037 0000 add [bx+si],al
00000039 0000 add [bx+si],al
0000003B 0000 add [bx+si],al
; Und noch mehr "NUL"s -> add [bx+si],al
read.elf vor kernelC.elf
Code:
00000000 E81300 call word 0x16
00000003 0000 add [bx+si],al
00000005 EA0000FFFF jmp word 0xffff:0x0
0000000A 0000 add [bx+si],al
0000000C 0000 add [bx+si],al
0000000E 0000 add [bx+si],al
00000010 B400 mov ah,0x0
00000012 CD16 int 0x16
00000014 B400 mov ah,0x0
00000016 C3 ret
00000017 008D4C24 add [di+0x244c],cl
0000001B 0483 add al,0x83
0000001D E4F0 in al,0xf0
0000001F FF71FC push word [bx+di-0x4]
00000022 55 push bp
00000023 89E5 mov bp,sp
00000025 51 push cx
00000026 83EC04 sub sp,byte +0x4
00000029 E8E2FF call word 0xe
0000002C FF db 0xff
0000002D FF db 0xff
0000002E B80000 mov ax,0x0
00000031 0000 add [bx+si],al
00000033 83C404 add sp,byte +0x4
00000036 59 pop cx
00000037 5D pop bp
00000038 8D61FC lea sp,[bx+di-0x4]
0000003B C3 ret
0000003C 0000 add [bx+si],al
0000003E 0000 add [bx+si],al
00000040 0000 add [bx+si],al
; Und noch mehr "NUL"s -> add [bx+si],al
EDIT3:
Kompletter Code:
kernel.asm
Code:
global start
start:
extern main
call main
global restart
restart:
db 0Eah
dw 0000h
dw 0FFFFh
kernel.c
C:
extern void read();
int main() {
read();
return 0;
}
read.asm
Code:
global read
read:
mov ah, 0x0
int 0x16
mov ah, 0
ret
Ich glaube, dass war's erstmal.

Zuletzt bearbeitet: