Autor Thema: char * bleibt leer  (Gelesen 7195 mal)

woigl

  • Beiträge: 93
    • Profil anzeigen
    • http://www.nogos.org
Gespeichert
« 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...

SSJ7Gohan

  • Beiträge: 398
    • Profil anzeigen
Gespeichert
« Antwort #1 am: 19. August 2005, 21:39 »
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.

maumo

  • Beiträge: 182
    • Profil anzeigen
    • http://maumo.50webs.com/
Gespeichert
« Antwort #2 am: 20. August 2005, 13:10 »
die asms wären hilfreicher

woigl

  • Beiträge: 93
    • Profil anzeigen
    • http://www.nogos.org
Gespeichert
« Antwort #3 am: 20. August 2005, 14:15 »
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...

hackgod

  • Beiträge: 70
    • Profil anzeigen
Gespeichert
« Antwort #4 am: 20. August 2005, 16:07 »
ich kann mich täuschen, aber müssen Strings nich wie folgt definiert werden?
char *Text[] = "Welcome!";


Wie gesagt, kann mich täuschen

woigl

  • Beiträge: 93
    • Profil anzeigen
    • http://www.nogos.org
Gespeichert
« Antwort #5 am: 20. August 2005, 16:13 »
Zitat von: hackgod
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!

SSJ7Gohan

  • Beiträge: 398
    • Profil anzeigen
Gespeichert
« Antwort #6 am: 20. August 2005, 16:34 »
char *var[];
Würde das gleiche wie char **var; bewirken, also ein Pointer auf einen Pointer auf ein Byte.

woigl

  • Beiträge: 93
    • Profil anzeigen
    • http://www.nogos.org
Gespeichert
« Antwort #7 am: 20. August 2005, 16:39 »
Zitat von: SSJ7Gohan
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!

SSJ7Gohan

  • Beiträge: 398
    • Profil anzeigen
Gespeichert
« Antwort #8 am: 20. August 2005, 16:42 »
Wird denn Text ausgegeben, oder liegt das Problem eventuell an der Ausgabe?

woigl

  • Beiträge: 93
    • Profil anzeigen
    • http://www.nogos.org
Gespeichert
« Antwort #9 am: 20. August 2005, 16:51 »
Zitat von: SSJ7Gohan
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!!

SSJ7Gohan

  • Beiträge: 398
    • Profil anzeigen
Gespeichert
« Antwort #10 am: 20. August 2005, 17:04 »
Änder
 .text  0x100000 :  {
    code = .; _code = .; __code = .;
    *(.text)
    . = ALIGN(4096);
  }

mal in
 .text  0x100000 :  {
    code = .; _code = .; __code = .;
    *(.text)
    *(.rodata*)
    . = ALIGN(4096);
  }

woigl

  • Beiträge: 93
    • Profil anzeigen
    • http://www.nogos.org
Gespeichert
« Antwort #11 am: 20. August 2005, 20:17 »
Zitat von: SSJ7Gohan
Ä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!

Legend

  • Beiträge: 635
    • Profil anzeigen
    • http://os.joachimnock.de
Gespeichert
« Antwort #12 am: 20. August 2005, 21:23 »
.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.
*post*

woigl

  • Beiträge: 93
    • Profil anzeigen
    • http://www.nogos.org
Gespeichert
« Antwort #13 am: 21. August 2005, 08:03 »
Zitat von: Legend
.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...

 

Einloggen