Lowlevel
Lowlevel => Lowlevel-Coding => Thema gestartet von: woigl am 19. August 2005, 21:22
-
Hi,
ich verwende Grub und einen C-Kernel...
Wenn ich in der Main() folgendes definiere:
char *text = "Welcome\0";
dann hab ich folgendes Phänomen wenn ich gleich anschliessend abfrage:
if (text[0]==0)
das in text[0] wirklich auch 0 drinnen steht -wie gibts das? für das brauche ich ja noch keinen Malloc - oder?
kann mir bitte jemand helfen? ich verzweifle...
-
Das \0 am ende kannst du weglassen, das macht gcc von alleine ;)
Warum text[0] == 0 ist, kann ich mir nicht erklären. Eigentlich sollte es den ASCII Code von "W" enthalten.
malloc() brauchst du dafür nicht. GCC legt "Welcome\0" in der Data Section ab, und sollte dann eigentlich in text einen Pointer auf diese Speicherstelle schreiben.
Es kann nur sein, das du irgentwas übersehen hast, gib mal deinen gesammten Code.
-
die asms wären hilfreicher
-
Hier nun mein kompletter Source...
Makefile:
CC = gcc
CFLAGS = -ffreestanding -c
ASMC = nasm
#-----------------------------------------------------------------------------
all: kernel32.bin
kernel32.bin: loader.o kernel.o
ld -T link.txt -o kernel32.bin loader.o kernel.o
kernel.o: kernel.c
$(CC) $(CFLAGS) kernel.c -o kernel.o
loader.o: loader.asm
nasm -f aout loader.asm -o loader.o
link.txt:
OUTPUT_FORMAT("binary")
ENTRY(start)
SECTIONS
{
.text 0x100000 : {
code = .; _code = .; __code = .;
*(.text)
. = ALIGN(4096);
}
.data :
{
data = .; _data = .; __data = .;
*(.data)
. = ALIGN(4096);
}
.bss :
{
bss = .; _bss = .; __bss = .;
*(.bss)
. = ALIGN(4096);
}
end = .; _end = .; __end = .;
}
loader.asm:
MULTIBOOT_PAGE_ALIGN equ 1<<0
MULTIBOOT_MEMORY_INFO equ 1<<1
MULTIBOOT_AOUT_KLUDGE equ 1<<16
MULTIBOOT_HEADER_MAGIC equ 0x1BADB002
MULTIBOOT_HEADER_FLAGS equ MULTIBOOT_PAGE_ALIGN | MULTIBOOT_MEMORY_INFO | MULTIBOOT_AOUT_KLUDGE
MULTIBOOT_CHECKSUM equ -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)
[BITS 32] ; protected mode.
[global start] ; Kernel entry point symbol.
[extern _main] ; this is our C code.
start:
mov [_mbinfo], ebx ; Save any multiboot data
mov [_mbmagic], eax
call _main ; Call our C code
abc123: ;Hang code in case main returns...
cli ; interrupts will disturb the halt
hlt ; halt the CPU
jmp abc123 ; In case halt is disturbed
;-------------------------------------------------------------
; Multi-Boot header.
;-------------------------------------------------------------
[global _mboot]
[global _mbinfo]
[global _mbmagic]
[extern code]
[extern bss]
[extern end]
ALIGN 4
_mboot:
dd MULTIBOOT_HEADER_MAGIC
dd MULTIBOOT_HEADER_FLAGS
dd MULTIBOOT_CHECKSUM
dd _mboot ; Location of this descriptor
dd code ; Start of kernel '.text' (code) section.
dd bss ; End of kernel '.data' section.
dd end ; End of kernel.
dd start ; Kernel entry point (initial EIP).
_mbinfo:
dd 0
_mbmagic:
dd 0
kernel.c:
int _main()
{
char *VideoMem = (char*)0xB8000;
char *Text = "Welcome to Protected Mode";
while(*Text)
{
*VideoMem = *Text;
*VideoMem++;
*VideoMem = 7;
*VideoMem++;
*Text++;
}
while(1)
asm volatile ("nop");
return(0);
}
Alles wird in Linux unter CentOS 3.1 kompiliert...
Also *Text scheint nach der Initialiserung leer zu sein... warum?
Sollte ich einen Fehler im Source haben, dann bitte ich euch dies richtig zu stellen...
-
ich kann mich täuschen, aber müssen Strings nich wie folgt definiert werden?
char *Text[] = "Welcome!";
Wie gesagt, kann mich täuschen
-
ich kann mich täuschen, aber müssen Strings nich wie folgt definiert werden?
char *Text[] = "Welcome!";
Wie gesagt, kann mich täuschen
nein, ausserdem streikt da auch der Compiler!
-
char *var[];
Würde das gleiche wie char **var; bewirken, also ein Pointer auf einen Pointer auf ein Byte.
-
char *var[];
Würde das gleiche wie char **var; bewirken, also ein Pointer auf einen Pointer auf ein Byte.
Ja aber das ergibt ja alles keinen Sinn, oder?
Ich denke mal das es eher nicht am C-Source liegt!
-
Wird denn Text ausgegeben, oder liegt das Problem eventuell an der Ausgabe?
-
Wird denn Text ausgegeben, oder liegt das Problem eventuell an der Ausgabe?
DEnke nicht das es daran liegt, denn wenn ich nur 1 Zeichen also ein char text = 'W'; ausgebe dann funktioniert es!!
-
Änder
.text 0x100000 : {
code = .; _code = .; __code = .;
*(.text)
. = ALIGN(4096);
}
mal in
.text 0x100000 : {
code = .; _code = .; __code = .;
*(.text)
*(.rodata*)
. = ALIGN(4096);
}
-
Änder
.text 0x100000 : {
code = .; _code = .; __code = .;
*(.text)
. = ALIGN(4096);
}
mal in
.text 0x100000 : {
code = .; _code = .; __code = .;
*(.text)
*(.rodata*)
. = ALIGN(4096);
}
:D :D :D es funktioniert - vielen vielen dank!
kannst mir vielleicht erklaeren was diese Aenderung genau ist und was es genau macht? bzw. kannst du mir das ganze linker skript erklaeren, da ich da noch nicht ganz durchsteige!
-
.rodata = Sektion für Read Only Daten, wie z.B. solche Strings.
Ohne diesen Eintrag sind die halt praktisch einfach weg! Allerdings scheint dies auch etwas von der gcc Version abzuhängen ob man .rodata braucht oder nicht.
-
.rodata = Sektion für Read Only Daten, wie z.B. solche Strings.
Ohne diesen Eintrag sind die halt praktisch einfach weg! Allerdings scheint dies auch etwas von der gcc Version abzuhängen ob man .rodata braucht oder nicht.
Auf jeden Fall mal vielen Danke - es hat funktioniert...