Lowlevel

Lowlevel => Lowlevel-Coding => Thema gestartet von: bitmaster am 18. January 2009, 23:44

Titel: Struktur auf beliebigen Speicher anwenden
Beitrag von: bitmaster am 18. January 2009, 23:44
Hi,

ich bin ja gerade dabei C zu lernen, wie ihr ja alle wisst.  :wink: So, nun habe ich irgendwo im Speicher einen speziellen Aufbau. Danach habe ich eine Struktur angefertigt. Jetzt stellt sich mir die Frage, wie ich diese Struktur auch dort anwenden kann.

Also sagen wir der Einfachheit halber hätte ich folgende Struktur:

struct WertePaar
{
u16 Wert1;
u32 Wert2;
};

Also u16 und u32 sind meine Definitionen in der types.h. So, jetzt wäre ab der Speicherstelle 0xBADCOOFE der Aufbau so wie in der Struktur WertePaar. Jetzt würde ich gerne diese Struktur dort anwenden. Wie kann ich das machen?

vielen dank schon mal

bitmaster
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: tarrox am 19. January 2009, 00:46
Du erzeugst einen Pointer und gibst diesen dann die Addresse. Jetzt kannst du mit -> auf die Member zugreifen.

WertePaar *NAME; //erzeuge Pointer
NAME = 0xBADC00FE; //Gib dem Pointer die gewollte Adresse
NAME->Wert1 = 10; //Wert1 wird geändert
NAME->Wert2 = (u32)NAME->Wert1; //Wert2 wird geändert
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: Jidder am 19. January 2009, 02:17
Die erste Zeile von tarrox klappt in C nicht (dafür aber in C++), die zweite sollte in beiden nicht gehen. (Compiler aus dem Kalten Krieg sehen das vielleicht etwas lockerer.) So klappts immer:
struct WertePaar *NAME; // <-- das struct gehört zum typen dazu
NAME = (struct WertePaar *) 0xBADC00FE; // <-- casten, damit der Compiler nicht weint

Wenn du struct nicht schreiben willst, befrage die Wissenquelle deiner Wahl nach typedef.
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: bitmaster am 19. January 2009, 21:06
Jo, scheint zu funktionieren. Vielen dank euch beiden.
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: bitmaster am 25. January 2009, 23:33
So, und weiter gehts mit der Fragerei. Also in der Variable multiboot_address steht die Adresse der multiboot (wer hätte es gedacht ^^). So, dann habe ich eine Struktur, die ich multiboot_info genannt habe. In meiner kernel.c habe ich dann das stehen:

struct multiboot_info *boot_info;
boot_info = (struct multiboot_info *) multiboot_address;

Jetzt kann ich ja mittels:

boot_info->ELEMENT
Darauf zugreifen. Alles schön und gut. Aber jetzt möchte ich außerhalb der kernel.c darauf zugreifen. Also ich habe jetzt eine mm.c in der ich auch mittels

boot_info->ELEMENT
darauf zugreifen möchte. Aber das geht ja nicht. Dann habe ich es mit extern versucht. Aber das funktioniert auch nicht. Ich weiß nicht was ich genau hinter extern schreiben soll. Also der muss ja den Aufbau der Struktur kennen und wo sich der ganze Krempel befindet. Also eher was für C Profis und nicht so Noobs wie mich.  :cry: Von daher wollte ich fragen ob ihr mir da evtl. helfen könnt.

thx

bitmaster
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: Termite am 26. January 2009, 10:20
Moin

extern heist so viel wie das die definition der Variable in einer anderen übersetzungseinheit erfolgt und nicht in der Aktuellen. Somit ein hinweis auf den Compiler/linker das er die variable trotzdem verwenden darf, und erst der Linker im hinterher angibt wo er das ding wirklich finden kann.

So als erstes sollte man sich in C angewöhnen 2 H Dateien zu verwalten. eine für den öffentliche teil, der andere für den Internen krempel, der auser im Modul sonst keinen was angeht. Zusätzlich zu den .C Dateien

MOD_C1.H öffentlicher teil des Moduls
typedef struct multiboot_info
{
    unsigned long int ELEMENT;
    unsigned long int ELEMENT1;
    unsigned long int ELEMENT2;
} multiboot_info_Type;

extern struct multiboot_info *boot_info;
/* oder alternative
extern multiboot_info_Type * boot_info;
*/


MOD_C1.C  Die implementierunt des Moduls
#include "MOD_C1.H"
boot_info = (struct multiboot_info *) multiboot_address;
/* oder alternative
boot_info = (multiboot_info_Type *) multiboot_address;

*/

ABC_Cx.C  ein anderes Modul
#include "MOD_C1.H"

boot_info->ELEMENT;


gruss
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: bitmaster am 26. January 2009, 20:33
Hi, vielen dank für deine Mühe.

Aber gcc meckert:

Zitat
MOD_C1.O: In function `main':
MOD_C1.C:(.text+0x1c): undefined reference to `boot_info'
MOD_C1.C:(.text+0x38): undefined reference to `boot_info'
MOD_C1.C:(.text+0x54): undefined reference to `boot_info'
ABC_Cx.O: In function `init_phys_mem':
ABC_Cx.C:(.text+0x4): undefined reference to `boot_info'

hmm...
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: bluecode am 26. January 2009, 20:39
in die MOD_C1.C muss noch
struct multiboot_info *boot_info;
die Definition von boot_info.
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: bitmaster am 26. January 2009, 21:40
in die MOD_C1.C muss noch
struct multiboot_info *boot_info;
die Definition von boot_info.
Dann sagt mir gcc noch:

Zitat
ABC_Cx.O: In function `init_phys_mem':
ABC_Cx.C:(.text+0x4): undefined reference to `boot_info'

Und wenn ich in der ABC_Cx.C einfach auch

struct multiboot_info *boot_info;
schreibe, dann stimmen dort die Werte nicht.  :-(

bitmaster
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: bluecode am 26. January 2009, 22:30
Wenn du das was du momentan hast irgendwo hochlädst würde ich es mir ansehen und könnte dir wahrscheinlich sagen wo das Problem liegt.
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: bitmaster am 26. January 2009, 23:24
OK, also ich habe eine multiboot.h, in der steht:

struct multiboot_info
{
u32 blabla
usw.
};

extern struct multiboot_info *boot_info;

Dann habe ich eine kernel.c, in der steht:

#include <multiboot.h>

void main(u32 multiboot_address, u32 multiboot_magic)
{
//clear screen
ClearScreen();

struct multiboot_info *boot_info;
boot_info = (struct multiboot_info *) multiboot_address;

test();

usw.
}

Dann habe ich eine test.c, in der steht:

#include <multiboot.h>

void test(void)
{
asm ("mov %0, %%eax" : : "m" (boot_info->ELEMENT));

while (1);
}

Dann lasse ich gcc compilieren und habe dann eine kernel.o und eine test.o. Mittels ld möchte ich die dann "zusammenlinken". Aber ld sagt dann:

Zitat
test.o: In function `test':
test.c:(.text+0x4): undefined reference to `boot_info'

bitmaster
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: Jidder am 26. January 2009, 23:38
Du hast mit extern struct multiboot_info *boot_info; nur den Zeiger deklariert, aber nicht definiert. Das heißt es gibt keinen zugeordneten Speicherbereich. Die Lösung ist also eine Definition mittels struct multiboot_info *boot_info;Die Zeile könnte z.B. in kernel.c unter den headern stehen.
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: Termite am 26. January 2009, 23:38
Nabend

und asche auf mein haupt,

in deiner kernel.c sollte noch die zeile von bluecode rein. ups is ja schon drinnen, nur im falschen kontext
#include <multiboot.h>

// muss global deklarirt werden! kann von allen funktionen dieser C Datei
// verwendet werden. wenn ein extern existiert auch von anderen
// übersetzungseinheiten. werden vom linker in den Data bereich abgelegt.

struct multiboot_info *boot_info;

// ein static reduziert die gültigkeit einer globalen variablen auf genau die C
// Datei in der sie definiert wurde. extern tut dann nicht mehr!

void main(u32 multiboot_address, u32 multiboot_magic)
{
//clear screen
ClearScreen();

// was hier deklariert wird hat nur gültigkeit inerhalb dieser funktion
// und sonst niergens nennen sich auch lokale variablen und werden
// meist auf dem Stack / heap angelegt.
boot_info = (struct multiboot_info *) multiboot_address;

test();

usw.
}
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: Jidder am 26. January 2009, 23:40
Hm, also ich mein das was Termite sagt ^^
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: bitmaster am 26. January 2009, 23:50
Ah  :-D und siehe da es tut.  :-o

Jo, ich muss mich noch ein wenig an dieser (HOCH)sprache gewöhnen. ^^

vielen dank euch  :-)

bitmaster
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: bitmaster am 28. January 2009, 19:11
Und da bin ich wieder.  :-D

So, es geht wieder um Strukturen. Hier ein Beispiel aus dem Internet:

#include <stdio.h>
 
struct person {
        short gewicht;
        short alter;
        short groesse;
};
 
int main()
{
        struct person p[3];
 
        p[0].gewicht = 70;
        p[0].alter = 22;
        p[0].groesse = 182;
 
        p[1].gewicht = 88;
        p[1].alter = 77;
        p[1].groesse = 166;
 
        p[2].gewicht = 95;
        p[2].alter = 50;
        p[2].groesse = 190;
 
        return 0;
}

Jetzt habe ich aber nicht 3 sondern X Personen. Sprich die Anzahl der Personen steht in einer Variable und wird erst zur Laufzeit ermittelt. Ist es dann möglich statt

struct person p[3];
einfach

struct person p[VARIABLE];
zu schreiben? Also mein gcc macht da irgendwas komisches wenn ich es so mache. Also zumindest kann ich den disassemblierten Code nicht nachvollziehen.

thx

bitmaster
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: rizor am 28. January 2009, 19:35
Hi,

das Problem ist, dass C keine dynamischen Arrays unterstützt (zumindest nicht ohne viele Tricks).
Du könntest dir eine Liste schreiben.
Das ist das einfachste.

Gruß
rizor
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: bitmaster am 28. January 2009, 19:39
Hi,

das Problem ist, dass C keine dynamischen Arrays unterstützt (zumindest nicht ohne viele Tricks).
Du könntest dir eine Liste schreiben.
Das ist das einfachste.

Gruß
rizor
THX

Hmm... schade, aber was meinst du mit "Liste"?

bitmaster
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: kevin am 28. January 2009, 19:41
Was bitmaster will, ist ein statisches Array auf dem Stack, dessen Größe zur Laufzeit bestimmt wird. Und das geht mit gcc (ist aber eine gcc-Erweiterung, wenn ich mich nicht irre).

void test(int x)
{
    int blubb[x];
    // ...
}
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: rizor am 28. January 2009, 19:44
struct linstenelement{
    struct listenelement *vorgaenger;
    struct person mensch;
    struct listenelement *nachfolger;
}

Das wäre eine doppelt verkettete Liste.
Dann bräuchtest du nur noch einen Pointer, der auf ein Element zeigt.
Dann gibt es zwei möglichkeiten:
1. Du machst eine doppelt verkettete Liste also an einem Element ist der Vorgaenger = NULL
und an einem Elemenet der Nachfolger  = NULL
2. Du baust eine Ringliste auf. also irgendwann zeigt das letzte Element auf das erste.
Da musst du halt nur aufpassen, dass du nicht in eine Endlosschleife läufst.

Was bitmaster will, ist ein statisches Array auf dem Stack, dessen Größe zur Laufzeit bestimmt wird. Und das geht mit gcc (ist aber eine gcc-Erweiterung, wenn ich mich nicht irre).

void test(int x)
{
    int blubb[x];
    // ...
}
Achso, ich dachte es geht einzig und allein um die Arrays.

Gruß
rizor
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: bitmaster am 28. January 2009, 20:11
Was bitmaster will, ist ein statisches Array auf dem Stack, dessen Größe zur Laufzeit bestimmt wird. Und das geht mit gcc (ist aber eine gcc-Erweiterung, wenn ich mich nicht irre).

void test(int x)
{
    int blubb[x];
    // ...
}
Hmm... das ist aber keine Struktur? Und bei mir wird die Variable x in der Fkt. test definiert. Ich habe aber das Gefühl, dass gcc die Variable x vorher herbei nimmt, sprich wenn sie den gewünschten Wert noch gar nicht hat. Denn es wird ganz zu beginn der Funktion test gemacht, obwohl ich der Variable x erst viel später einen Wert zuweise (wenn ich den assemblierten Code richtig deute).

bitmaster
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: kevin am 28. January 2009, 20:16
Wie sieht dein Code denn konkret aus? Wenn die Variablendeklaration kommt, nachdem du x einen Wert zugewiesen hast, sollte das eigentlich funktionieren. Und ob es ein Array über ints oder irgendwelche structs ist, ist egal - sind beides nur Pointer. ;)
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: bitmaster am 28. January 2009, 20:36
So, ich war jetzt mal so frei und habe mir euren LOST-Code angesehen (bzw. wie heißt euer OS noch gleich tyndur oder so?). Da macht ihr folgendes:

struct multiboot_mmap * mmap;
    struct {
        dword start;
        dword end;
    } available_memory[16 + (3 * multiboot_info.mi_mods_count)];

Wie ihr da auf 16 und 3 kommt weiß ich zwar nicht, aber macht ihr da nicht das was ich auch haben will? Ich meine multiboot_info.mi_mods_count ist doch eine Variable die einen Wert zur Laufzeit zugewiesen bekommt, oder net? Von daher wäre das doch das was ich meinte, oder net?

@taljeth:

also ungefähr so sieht mein Code aus:

void test(void)
{
int counter = 0;

//blabla = Code der mit dieser Sache nichts zu tun hat

//eine do .. while schleife die den Wert von counter erhöht

//jo und hier würde ich dann gerne meine Struktur(en) mittels counter aufbauen
}
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: bluecode am 28. January 2009, 21:21
Was bitmaster will, ist ein statisches Array auf dem Stack, dessen Größe zur Laufzeit bestimmt wird. Und das geht mit gcc (ist aber eine gcc-Erweiterung, wenn ich mich nicht irre).
Das ist im C99 Standard.
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: bitmaster am 28. January 2009, 21:39
Na ja OK vielen dank. Ich schaue mir das dann frühstens morgen an. Ich muss jetzt weg.

5:1 *hust* äh ich meine bitmaster  :-D
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: Termite am 29. January 2009, 10:00
Moin Moin

das was ihr sucht kann jeder c compiler und nennt sich malloc, realloc und free.

wenn sich zur laufzeit die grösse des arrays nicht verändert, sondern nur bestimmt werden muss, ist das der einfachste weg.

sollte sich zur laufzeit die grösse des Arrays verändern, ist eine Liste die beste wahl. wobei man auch bei einer liste um malloc und free nicht drum herumkommt. und ob nun einfach doppelt verkettet, oder doch lieber ein baum, oder doch lieber gleich nen wald ( ein baum aus bäumen) ist dann geschmakssache, bzw hängt von den anforderungen an die liste ab.

wobei die einfachste version für eine dynamisch wachsende Liste realloc, bzw. ein malloc mit memcopy und einen free der alten liste währe.

gruss

ps. und in C++ würde ich euch die STL ans herz legen. wieso das rad neu erfinden, wenn sich schlaue köpfe schon das hirn verränkt haben und die fast optimale implementierung gefunden haben ( list, map, hashmap, sortiert, nicht sortiert, optimiert auf linaren zugriff, ... ) bzw Boost

Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: Jidder am 29. January 2009, 10:41
Das Problem ist, dass diese tollen Funktionen nicht in jedem Betriebssystemkernel zur Verfügung stehen. Und ohne vorher einiges zu tun, erst recht nicht ;)
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: kevin am 29. January 2009, 11:18
das was ihr sucht kann jeder c compiler und nennt sich malloc, realloc und free.
Falls du meinst, daß jeder C-Compiler Funktionsaufrufe kann, hast du vermutlich recht. Ansonsten hat er wenig mit malloc/free zu tun. ;)
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: Termite am 29. January 2009, 12:05
Moin Moin

ich arbeite teilweise auch ohne OS bzw mit sehr exotischen sachen microC/OS-II auf einem ARM 7 z.B. Malloc und free werden mir vom compiler zur verfügung gestellt. voraussetzung ist, das ich einen heap definiere, im embeded bereich macht man das meist statisch, da so viel speicher gar nicht vorhanden ist.

gcc hat sicher auch eigene Funktionen für malloc und free. die gehen sicher intern wieder auf andere Fuktionen, die man ggf erst implementieren muss. z.B. um vom os speicher für den heap anzufordern.
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: bitmaster am 31. January 2009, 12:52
So, nochmal was anderes in C. Ich möchte wenn eine Bedingung erfüllt ist eine Funktion verlassen. Wie mache ich das? Also ich meine das hier:

u8 test(void)
{
if (bla)
{
bla
}

else
{
bla

if (bla)
{
bla
return 1;
//ich will nach hallo
}

bla
return 0;
}

//hier ist hallo
}

Wie "springe" ich nach der Stelle, die ich hallo genannt habe?

thx

bitmaster
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: bluecode am 31. January 2009, 13:01
//blub

goto hallo

//blub

hallo:
//bla
Aber abhängig davon was genau du machen willst, ist eventuell das Design deiner Funktion(en) Schrott. In höheren Sprachen ist goto considered harmful (http://en.wikipedia.org/wiki/Considered_harmful), weil es das "intuitive Codeverständnis" extrem behindert.
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: kevin am 31. January 2009, 13:10
Wobei C noch nicht so höher ist, daß es dort absolut gelten würde. Faustregel: Dort, wo man in anderen Sprachen Exceptions verwenden würde, können gotos angebracht sein, unter Umständen auch noch als eine Art mehrstufiges break (also nicht nur eine Schleife abbrechen, sondern die umgebende gleich mit). Rückwärtssprünge mit goto sind extrem schlechter Stil (und deswegen z.B. im qemu-Source anzutreffen :-D)
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: bitmaster am 31. January 2009, 13:18
Ja an so etwas wie break habe ich dabei gedacht. Nur wie genau mache ich das in meinem Beispiel? Wenn ich das break hinter der if Schleife schreibe, dann wird es ja auch "ausgeführt" wenn die if-Bedingung nicht erfüllt ist. Aber das soll ja nicht.  :?
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: bluecode am 31. January 2009, 13:20
if Schleife
-> http://www.if-schleife.de/ (http://www.if-schleife.de/)
Insofern ist break da fehl am Platz.
Wie gesagt, goto würde das tun was du möchtest (webei ein goto direkt hinter einem return auch sinnlos ist), aber es ist nicht unbedingt der Königsweg.
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: bitmaster am 31. January 2009, 13:21
if Schleife
-> http://www.if-schleife.de/ (http://www.if-schleife.de/)
Insofern ist break da fehl am Platz.
^^ Na dann, dann werde ich es wohl mit goto machen müssen. thx
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: bluecode am 31. January 2009, 13:25
Sag mal bitmaster, magst du vielleicht begründen, warum du von Assembler zu C (bzw. allgemein zu eine höheren Programmiersprache) gewechselt bist? Vielleicht könnten einige andere davon was lernen und mich würde es natürlich interessieren (und ich denke die anderen in #lost auch :-D ).
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: bitmaster am 31. January 2009, 13:32
Sag mal bitmaster, magst du vielleicht begründen, warum du von Assembler zu C (bzw. allgemein zu eine höheren Programmiersprache) gewechselt bist? Vielleicht könnten einige andere davon was lernen und mich würde es natürlich interessieren (und ich denke die anderen in #lost auch :-D ).
Wenn du mir eine Vernünftige Lösung für mein Problem bietest, gerne ja. Also gcc meckert jetzt rum, dass am Ende der Funktion ein Label steht:

Zitat
mm.c: In function ‘init_phys_mem’:
mm.c:146: error: label at end of compound statement

bitmaster
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: kevin am 31. January 2009, 13:38
Mach einfach ein return; dahinter rein.
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: bitmaster am 31. January 2009, 14:04
Mach einfach ein return; dahinter rein.
Ja klasse, dann ist ja der Sinn dahin. ^^ Ich mache vor dem goto ja schon ein return 1 (Fehlercode).

Zumal gcc dann auch meckert:

error: ‘return’ with no value, in function returning non-void
bitmaster
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: bitmaster am 31. January 2009, 14:24
Man irgendwie geht gar nichts mehr. Man ist wirklich total eingeschrenkt mit einer Hochsprache (alleine wenn ich denke wie schlecht die Compiler "optimieren"). Also noch ein Problem. Was ist denn jetzt hier falsch?

u32 beispiel = 0xB8000;
u8 *pointer;
pointer = beispiel; //wieso geht das nicht?

while (bla)
{
*pointer = 0x00;
pointer++;
}

gcc meckert:

Zitat
error: assignment makes pointer from integer without a cast

man man man, ich kriege hiermit noch mal kA ^^

bitmaster
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: bitmaster am 31. January 2009, 15:12
bestes Beispiel:

mov    -0x2c(%ebp),%eax
sub    $0x8,%eax
mov    %eax,-0x2c(%ebp)
mov    -0x2c(%ebp),%eax
cmp    $0x7,%eax
ja     bla

Boar wenn ich so etwas sehe, dann muss ich fast *zensier*.

bitmaster
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: FreakyPenguin am 31. January 2009, 15:25
Mach einfach ein return; dahinter rein.
Ja klasse, dann ist ja der Sinn dahin. ^^ Ich mache vor dem goto ja schon ein return 1 (Fehlercode).

Nach einem return wird aber nichts mehr ausgeführt, da die Funktion dann verlassen wird, was ja genau Sinn vom return ist.


Und zu deinem 2. Problem: Ja eine Hochsprache schränkt ein, damit man nicht einfach unabsichtlich jede Dummheit machen kann. Und genau so einen Fall hast du da erwischt: Normalerweise will man einem Pointer keine anderen Werte als andere Pointer zuweisen, deshalb geht dein Compiler davon aus, dass du nicht pointer = beispiel meinst sondern vermutlich eher *pointer = beispiel. Wenn du das aber wirklich so meinst musst du casten: pointer = (u8*) beispiel;
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: bitmaster am 31. January 2009, 15:48
Jo, dass mit dem (u8*) habe ich schon herausgefunden. Aber wieso erzeugt gcc einen so Grotten schlechten Code? Also Sachen wie rep, scasx, movsx etc. erzeugt er nicht. Stattdessen langsame Sachen. Und wie oben schon gepostet kopiert er Sachen in Register, die dort bereits stehen. Und auch mit der Option -o oder -o3 ist es nicht wirklich besser. Also ich bin nach wie vor davon überzeugt, dass man mit ASM weitaus besseren Code erzeugen kann. Aber na ja, ich "muss" ja C nehmen.  :x

bitmaster
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: bluecode am 31. January 2009, 17:02
Zeig mir erstmal den Code, die verwendeten Kommandozeilenoptionen und die gcc Version zu dem Assembleroutput von oben. Abgesehen davon frage ich mich wie du darauf kommst, dass nur weil du weniger Assemblerinstruktionen verwendest das schneller ausgeführt wird. Das ist i.A. nämlich überhaupt nicht der Fall.

Ansonsten schau dir auch mal die -march Kommandozeilenoption (http://gcc.gnu.org/onlinedocs/gcc-4.3.3/gcc/i386-and-x86_002d64-Options.html#i386-and-x86_002d64-Options) an.
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: bitmaster am 31. January 2009, 18:29
Zeig mir erstmal den Code, die verwendeten Kommandozeilenoptionen und die gcc Version zu dem Assembleroutput von oben. Abgesehen davon frage ich mich wie du darauf kommst, dass nur weil du weniger Assemblerinstruktionen verwendest das schneller ausgeführt wird. Das ist i.A. nämlich überhaupt nicht der Fall.

Ansonsten schau dir auch mal die -march Kommandozeilenoption (http://gcc.gnu.org/onlinedocs/gcc-4.3.3/gcc/i386-and-x86_002d64-Options.html#i386-and-x86_002d64-Options) an.
Ich glaube aber schon, dass wenn ein Wert bereits in einem Register steht, es schneller ist, wenn man es nicht noch einmal dort rein kopiert.
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: bitmaster am 31. January 2009, 18:47
Zitat
Nach einem return wird aber nichts mehr ausgeführt, da die Funktion dann verlassen wird, was ja genau Sinn vom return ist.
:? Der Befehl return kopiert doch nur einen Wert nach al, ax, eax oder rax als Rückgabewert. Mit dem Rücksprung (leave + ret etc.) hat er doch nichts zu tun. Oder vertue ich mich da?

bitmaster
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: kevin am 31. January 2009, 18:48
Ja, du irrst dich. return beendet die Funktion und führt dementsprechend auch den Rücksprung durch.
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: bitmaster am 31. January 2009, 18:54
Ups, Problem mit else gelöst.  :-D

Ja, du irrst dich. return beendet die Funktion und führt dementsprechend auch den Rücksprung durch.
Nein, tut es nicht. Der Befehl return kopiert nur einen Wert - in meinem Fall nach -0x39(%ebp). Und das letzte "}" kopiert -0x39(%ebp) dann nach eax, führt ein leave und ein ret aus. ätsch

bitmaster

EDIT: Bzw. wenn das return ganz unten steht habt ihr recht. Aber wenn nicht, dann habe ich recht,  :-P
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: Homix am 31. January 2009, 19:12
Ups, Problem mit else gelöst.  :-D

Ja, du irrst dich. return beendet die Funktion und führt dementsprechend auch den Rücksprung durch.
Nein, tut es nicht. Der Befehl return kopiert nur einen Wert - in meinem Fall nach -0x39(%ebp). Und das letzte "}" kopiert -0x39(%ebp) dann nach eax, führt ein leave und ein ret aus. ätsch

bitmaster

EDIT: Bzw. wenn das return ganz unten steht habt ihr recht. Aber wenn nicht, dann habe ich recht,  :-P

wie kommst du überhaupt darauf, dass return nur einen Wert in ein Register kopiert und nicht zurückspringt? Und die Assemblerbefehle ("-0x39(%ebp) ") und so sagen mir eigentlich nichts ohne zusammenhang, und wenn schon, wenn du schon C disassemblierst, solltest du wenigstens Assembler (lesen) können  :-)

Grüsse,
Stefan
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: kevin am 31. January 2009, 19:16
Nein, tut es nicht. Der Befehl return kopiert nur einen Wert - in meinem Fall nach -0x39(%ebp). Und das letzte "}" kopiert -0x39(%ebp) dann nach eax, führt ein leave und ein ret aus. ätsch

bitmaster

EDIT: Bzw. wenn das return ganz unten steht habt ihr recht. Aber wenn nicht, dann habe ich recht,  :-P

#include <stdio.h>

char* wer;

void test()
{
    int x = 0;

    wer = "taljeth";
    if (x == 0)
        return;

    wer = "bitmaster";
}

int main(void)
{
    test();
    printf("%s hat recht\n", wer);
    return 0;
}

Have fun. ;)

Und hier nochmal in Assembler. Er springt beim return eindeutig über den Rest der Funktion weg direkt zum leave/ret:

00000000 <test>:
   0:   55                      push   %ebp
   1:   89 e5                   mov    %esp,%ebp
   3:   83 ec 10                sub    $0x10,%esp
   6:   c7 45 fc 00 00 00 00    movl   $0x0,0xfffffffc(%ebp)
   d:   c7 05 00 00 00 00 00    movl   $0x0,0x0
  14:   00 00 00
  17:   83 7d fc 00             cmpl   $0x0,0xfffffffc(%ebp)
  1b:   74 0a                   je     27 <test+0x27>
  1d:   c7 05 00 00 00 00 08    movl   $0x8,0x0
  24:   00 00 00
  27:   c9                      leave
  28:   c3                      ret
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: bitmaster am 31. January 2009, 19:18
stefan2005: Nur weil die Assemblerbefehle dir nichts sagen, heißt das noch lange nicht, dass ich kein Assembler lesen könnte (wobei die intel syntax mir angenehmer ist). Und ja, return kopiert einen Wert in den RAM mit Hilfe von ebp/rbp, wenn es nicht ganz unten steht (dort kopiert es den Wert direkt nach al/ax/ax/rax). Wie ich darauf komme? Ich disassembliere und mache dann guck guck.  :wink:

bitmaster

taljeth: mag sein bei einem return ohne Parameterübergabe. Aber das ist bei meiner Funktion wie bereits gesagt nicht möglich. Da ich nicht void sondern u8 als Rückgabetyp angebe. Von daher bewirkt ein return 1 folgendes:

//return 1
100c64:       c6 45 c7 01             movb   $0x1,-0x39(%ebp)
100c68:       e9 96 00 00 00          jmp    100d03 <test+0x337>
//anderer code +
//return 0
100cff:       c6 45 c7 00             movb   $0x0,-0x39(%ebp)
100d03:       0f b6 45 c7             movzbl -0x39(%ebp),%eax
100d07:       83 c4 44                add    $0x44,%esp
100d0a:       5b                      pop    %ebx
100d0b:       5e                      pop    %esi
100d0c:       5f                      pop    %edi
100d0d:       c9                      leave
100d0e:       c3                      ret

tjo so sieht das dann halt aus
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: Termite am 31. January 2009, 19:28
So, nochmal was anderes in C. Ich möchte wenn eine Bedingung erfüllt ist eine Funktion verlassen. Wie mache ich das? Also ich meine das hier:

u8 test(void)
{
if (bla)
{
bla
}

else
{
bla

if (bla)
{
bla
return 1;
//ich will nach hallo
}

bla
return 0;
}

//hier ist hallo
}

Wie "springe" ich nach der Stelle, die ich hallo genannt habe?

thx

bitmaster

zurück mal zum ursprünglichen Problem ein else würde da schon wunder bewirken.

goto in c find ich hässlich. kann verwendet werden.  sollte aber vermieden werden. und so kompliziert verschachtelte schleifen baut ihr nun auch noch nicht. und wenn sollte man sich überlgen obs nicht doch anders geht.

u8 test(void)
{
        u8 ret;

        ret = 0;
if (bla)
{
bla
                ret = -2;
}
else
{
bla

if (bla)
{
bla
ret = 1;
//ich will nach hallo
}
                else
                {
    bla
    ret = 0;
                }
}

return ret;
}
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: bitmaster am 31. January 2009, 19:31
Termite: siehe weiter oben, da steht:

Zitat
Ups, Problem mit else gelöst.   :-D

 :-)

taljeth: ok hast recht, das

jmp    100d03 <test+0x337
ist nicht von dem Ende des IFs, sondern vom return 1. *duck*
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: kevin am 31. January 2009, 19:38
taljeth: mag sein bei einem return ohne Parameterübergabe. Aber das ist bei meiner Funktion wie bereits gesagt nicht möglich. Da ich nicht void sondern u8 als Rückgabetyp angebe.
Dann änder den Rückgabetyp in meinem Beispiel eben. Wird dasselbe rauskommen. Ehrlich du, ich kenn C halbwegs. ;)

Zitat
Von daher bewirkt ein return 1 folgendes:

//return 1
100c64:       c6 45 c7 01             movb   $0x1,-0x39(%ebp)
100c68:       e9 96 00 00 00          jmp    100d03 <test+0x337>
//anderer code +
//return 0
100cff:       c6 45 c7 00             movb   $0x0,-0x39(%ebp)
100d03:       0f b6 45 c7             movzbl -0x39(%ebp),%eax
100d07:       83 c4 44                add    $0x44,%esp
100d0a:       5b                      pop    %ebx
100d0b:       5e                      pop    %esi
100d0c:       5f                      pop    %edi
100d0d:       c9                      leave
100d0e:       c3                      ret
Was uns sagt, daß er über das movb für den Rückgabewert hinweg zum Funktionsende springt. Was war jetzt nochmal das Problem? [edit: Ah, du hast's eingesehen. ;) ]
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: bluecode am 31. January 2009, 21:34
Ich disassembliere und mache dann guck guck.  :wink:
Ich halte das für keinen sinnvollen Weg eine (Hoch-) Sprache zu lernen.
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: bitmaster am 31. January 2009, 21:52
Ich disassembliere und mache dann guck guck.  :wink:
Ich halte das für keinen sinnvollen Weg eine (Hoch-) Sprache zu lernen.
Ich schon, wird immer besser.  :-D
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: bitmaster am 31. January 2009, 22:00
So Kinders, ich gehe jetzt schlafen, damit ich morgen früh fit bin, beim Schauen von Federer vs. Nadal. Hoffentlich zieht Federer Nadal ab.

So und trotz des 0:1: Bayern wird Meister.

Tschau und gute Nacht.

bitmaster

 :-D
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: bitmaster am 03. February 2009, 14:54
So, jetzt mal was ganz anderes. Auch wenn es nichts mit C zu tun hat, so habe ich keine Lust ein neues Thema auf zumachen. Also folgendes: Ich bin gerade dabei die physikalische Speicherverwaltung fertig zu machen. Ich habe eine memory bitmap, in der jedes Bit für eine 4 KByte Page steht. Ist das Bit gesetzt, so ist die Page belegt, ansonsten ist sie frei. Alles wunderbar, funktioniert auch soweit. Ich gehe so vor: Erstmal setze ich alle Bits, dann werden die gelöscht, die nach der mmap gelöscht sein sollten. Dann werden die gesetzt, die die Pages der Module wiederspiegeln, dann werden die gesetzt, die den Ort der memory bitmap wiederspiegeln (wenn ich das jetzt mal so ausdrücken darf). Tja und zuletzt würde ich gern die Bits setzten, die den Kernel betreffen. Der fängt ja bei 1 MByte an. Nur dazu müsste ich die genaue Größe des Kernels wissen. Und da ist schon das Problem. Wenn ich in meiner kernel.asm folgendes schreiben würde

...
section '.bss'
 rb 0x10000
 kstack: ;Stack wächst nach unten
kernel_end ;Ende des Kernels

und dann einfach kernel_end minus 1 MByte, dann hätte ich ja "eigentlich" die Größe des Kernels. Nur halt, C speichert lokale Variablen doch in der Section bss ab, oder? Also zumindest weiß ich, dass mein Kernel bei kernel_end nicht zu ende ist. Tjo, also wie bekomme ich jetzt die tatsächliche Größe meines Kernels raus? Eine Möglichkeit wäre ja sich den ersten Eintrag des Moduls vorzunehmen und sich dort multiboot_module->start anzuschauen. Dort beginnt ja das erste Modul. Nur kann man darauf vertrauen, dass es wirklich direkt hinter dem Kernel ist (also bei mir jetzt ja, aber ist es auch IMMER so?). Also ich wäre euch sehr dankbar wenn ihr mir da helfen könntet.

Ach ja, aber dass die Startadressen der Module ein Vielfaches von 4 KByte sind, darauf kann man doch vertrauen, oder (auch) nicht?

thx

bitmaster
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: kevin am 03. February 2009, 15:18
Das Symbol kernel_end im Linkerskript setzen statt in einer Sourcedatei. Der Linker ist der einzige, der weiß, wo er wirklich fertig ist.

Das mit dem Align auf 4K ist bei GRUB auf jeden Fall so. Bin mir nicht hundertprozentig sicher, ob es auch in der Spezifikation steht.
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: bitmaster am 03. February 2009, 15:41
Das Symbol kernel_end im Linkerskript setzen statt in einer Sourcedatei. Der Linker ist der einzige, der weiß, wo er wirklich fertig ist.

Das mit dem Align auf 4K ist bei GRUB auf jeden Fall so. Bin mir nicht hundertprozentig sicher, ob es auch in der Spezifikation steht.
Ah vielen dank. Aber wie genau mache ich das im Linkerskript? So funktioniert es zumindest nicht:

ENTRY (loader)

SECTIONS
{
. = 0x00100000;

.text :
{
*(.text)
}

.rodata ALIGN (0x1000) :
{
*(.rodata)
}

.data ALIGN (0x1000):
{
*(.data)
}

.bss :
{
_sbss = .;
*(COMMON)
*(.bss)
_ebss = .;
}

kernel_end = .;
}

Und dann habe ich im source folgendes stehen:

extern u32 kernel_end;
Aber dann hat kernel_end den Wert 0x0 und das kann ja unmöglich richtig sein.

thx

bitmaster
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: bitmaster am 03. February 2009, 16:47
hmm weiß keine ne Lösung?
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: tarrox am 03. February 2009, 16:57
Du musst auf die Addresse von kernel_end zugreifen und nicht auf das worauf es zeigt.
u32int* pointer = (u32int*)kernel_end; //Du greifst auf den inhalt an der Addresse von Kernelende zu, das willst du ja nicht
u32int* pointer = &kernel_end; //der Pointer zeigt auf das Ende des Kernels
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: Jidder am 03. February 2009, 17:10
hmm weiß keine ne Lösung?
Hey, wenn du Antwortzeiten von unter einer Stunde erwartest, komm ins IRC ;)
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: bitmaster am 03. February 2009, 17:25
ich weiß die Antwort:

extern void kernel_end(void);
 :-D
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: Jidder am 03. February 2009, 17:32
Wo haste dir denn den Trick abgeschaut? :P
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: bitmaster am 03. February 2009, 17:40
Wo haste dir denn den Trick abgeschaut? :P
bei Franck Ribery  :-P
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: bluecode am 03. February 2009, 18:24
Das mit dem Align auf 4K ist bei GRUB auf jeden Fall so. Bin mir nicht hundertprozentig sicher, ob es auch in der Spezifikation steht.
Steht da sehr wohl drin, wobei man dafür bit0 der Flags setzen muss, siehe Multiboot Specification (http://www.gnu.org/software/grub/manual/multiboot/multiboot.html#Header-magic-fields).
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: bitmaster am 03. February 2009, 18:43
Das mit dem Align auf 4K ist bei GRUB auf jeden Fall so. Bin mir nicht hundertprozentig sicher, ob es auch in der Spezifikation steht.
Steht da sehr wohl drin, wobei man dafür bit0 der Flags setzen muss, siehe Multiboot Specification (http://www.gnu.org/software/grub/manual/multiboot/multiboot.html#Header-magic-fields).
Gut dass du das sagst Junge, das Flag war bei meinem Kernel nämlich gelöscht.

bitmaster
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: bluecode am 03. February 2009, 18:56
Zitat
Junge, nenn mich nicht Junge!
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: bitmaster am 03. February 2009, 19:04
Zitat
Junge, nenn mich nicht Junge!
Junge, was meinen die mit Bit1? Wenn keine mmap vorhanden ist, dass dann die mem-felder vorhanden sein müssen?hä?

 :-o :? :-( :cry: :? :-o :x :? :-o
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: bluecode am 03. February 2009, 19:29
ehm... hä? Da steht, dass wenn du Bit 1 der Multiboot Header setzt, dass dann mindestens die mem_* Elemente der Multiboot Information Structure gültig sind (Anmerkung: ansonsten darf der Bootloader dein OS nicht laden) und falls der Bootloader fähig ist eine Memory-Map dir mit auf den Weg zu geben und noch dazu einen Memory-Map vorhanden ist (Anmerkung: über das BIOS), dann darf der Bootloader auch die mmap_* Elemente füllen.
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: bitmaster am 03. February 2009, 20:32
ehm... hä? Da steht, dass wenn du Bit 1 der Multiboot Header setzt, dass dann mindestens die mem_* Elemente der Multiboot Information Structure gültig sind (Anmerkung: ansonsten darf der Bootloader dein OS nicht laden) und falls der Bootloader fähig ist eine Memory-Map dir mit auf den Weg zu geben und noch dazu einen Memory-Map vorhanden ist (Anmerkung: über das BIOS), dann darf der Bootloader auch die mmap_* Elemente füllen.
Ja das kann ich auch lesen. Und wenn Bit1 nicht gesetzt ist? Was ist dann anders?

bitmaster
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: bluecode am 03. February 2009, 21:21
Dann darf der Bootloader dich auch laden wenn er nicht mem_* füllen kann. Die Flags in der Multiboot Header sagen einfach dem Bootloader was er mindestens tun muss um laden zu dürfen. ("The field `flags' specifies features that the OS image requests or requires of an boot loader.")
Die Flags in der Multiboot Information Structure hingegen sagen dir was der Bootloader wirklich getan hat. ("The first longword indicates the presence and validity of other fields in the Multiboot information structure. All as-yet-undefined bits must be set to zero by the boot loader. Any set bits that the operating system does not understand should be ignored. Thus, the `flags' field also functions as a version indicator, allowing the Multiboot information structure to be expanded in the future without breaking anything.")
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: bitmaster am 03. February 2009, 21:53
Zitat
Dann darf der Bootloader dich auch laden wenn er nicht mem_* füllen kann.
Mich darf er laden? oO besser nicht  :lol: die mem_* werden wohl eher "gefüllt" sein als die mmap_*. Bei meinem alten Notebook sind die mmap_* Felder z.B. nicht "gefüllt" aber die mem_* schon.

bitmaster
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: bitmaster am 05. February 2009, 12:53
So, welche Größe hat __SIZE_TYPE__ eigentlich?

Und was ist der Unterschied zwischen const char *bla und char *bla?

Äh was gibts noch, hmm... später.  :lol:

bitmaster

EDIT: Ah, const ist sozusagen ein Schreibschutz, stimmts? Ich kann dann *bla nicht beschreiben. Zumindest wenn ich mein Buch richtig verstanden habe.

EDIT2: Bin gerade dabei die ersten Sachen für die libc zu machen (also strlen und so). Jetzt muss ich den kram ja mit gcc compilieren und habe dann eine *.o. Und weiter? Ich habe gesehen, dass das in Linux in ein *.a Archiv gepackt wird. Wie mache ich das? Und wie bringe ich gcc dazu, dass er dieses Archiv kennt, damit umgehen kann und es "immer" heranzieht. Also das Archiv müsste ich ja mit ar bauen können. Nur bei mir tut sich da nichts.

EDIT3: OK ich habs jetzt gebacken gekriegt mit dem Archiv. Aber wie sage ich dem gcc jetzt das er mit dem Archiv arbeiten soll?

thx

bitmaster
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: bluecode am 05. February 2009, 14:36
So, welche Größe hat __SIZE_TYPE__ eigentlich?
sizeof(__SIZE_TYPE__)


Zitat
Und was ist der Unterschied zwischen const char *bla und char *bla?
Ersteres ist ein Zeiger der auf etwas was über diesen Zeiger nicht (ohne Cast) verändert werden darf zeigt. Letzteres ist ein "normaler" Zeiger.

Zitat
EDIT: Ah, const ist sozusagen ein Schreibschutz, stimmts? Ich kann dann *bla nicht beschreiben. Zumindest wenn ich mein Buch richtig verstanden habe.
Ja.

Zitat
EDIT2: Bin gerade dabei die ersten Sachen für die libc zu machen (also strlen und so). Jetzt muss ich den kram ja mit gcc compilieren und habe dann eine *.o. Und weiter? Ich habe gesehen, dass das in Linux in ein *.a Archiv gepackt wird. Wie mache ich das? Und wie bringe ich gcc dazu, dass er dieses Archiv kennt, damit umgehen kann und es "immer" heranzieht. Also das Archiv müsste ich ja mit ar bauen können. Nur bei mir tut sich da nichts.
Beispiel: ar rc libc.a bla.o bla2.o

Zitat
EDIT3: OK ich habs jetzt gebacken gekriegt mit dem Archiv. Aber wie sage ich dem gcc jetzt das er mit dem Archiv arbeiten soll?
Beim Linken nimmt man einfach das Archiv dazu (genauso wie eine Objektdatei auch).
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: bitmaster am 05. February 2009, 14:40
bluecode: Ah cool, danke.

So noch was, ich habe einen Zeiger namens *boot_inf. Mittels boot_inf bekomme ich ja jetzt den Wert der Adresse. Aber wieso darf ich mit dem nicht rechnen bzw. kann ich das doch irgendwie erzwingen?

thx

bitmaster
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: bluecode am 05. February 2009, 14:44
Du darfst mit dem sehr wohl rechnen, aber es wird nicht das sein was du dir vorstellst. zB:
T *t = 0;
++t;
Unter der Annahme, dass T ein Typ der Größe s ist, ist nach diesem Codestück t = 0 + 1 * s = s, d.h. es wird anstatt ein Byte weiterzugehen einmal s Bytes weitergegangen.

Wenn du wirklich bytes weitergehen möchtest, dann macht man das so:
T *t = 0;
t = (T*)((uintptr_t)t + x)
wobei x die Anzahl der Bytes ist die du weiter möchtest.
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: bitmaster am 05. February 2009, 14:48
Du darfst mit dem sehr wohl rechnen, aber es wird nicht das sein was du dir vorstellst. zB:
T *t = 0;
++t;
Unter der Annahme, dass T ein Typ der Größe s ist, ist nach diesem Codestück t = 0 + 1 * s = s, d.h. es wird anstatt ein Byte weiterzugehen einmal s Bytes weitergegangen.

Wenn du wirklich bytes weitergehen möchtest, dann macht man das so:
T *t = 0;
t = (T*)((uintptr_t)t + x)
wobei x die Anzahl der Bytes ist die du weiter möchtest.
Äh ok, das mit dem inkrementieren/decrementieren habe ich schon gemerkt und in meinem Buch nachgelesen. Ich meinte mit "rechnen" jetzt aber was anderes. Aber ich habe es schon herausgefunden, mit (u32)boot_inf gehts. Aber trotzdem danke.

bitmaster
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: bluecode am 05. February 2009, 14:50
Exakt dieses meinte ich mit uintptr_t... Zumindest wäre das der standard(konforme) Weg dies zu tun. Mit (u32) kriegst du im Longmode offensichtlich Probleme. Wie gesagt, Portabilität ist keine Eigenschaft einer (Hoch-)Sprache (edit: Aber erst Hochsprachen machen Portabilität möglich, falls jetzt wieder einer der Fließbandjungs kommt und nörgelt), sondern eher eine guten Codes.
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: bitmaster am 05. February 2009, 15:30
Exakt dieses meinte ich mit uintptr_t... Zumindest wäre das der standard(konforme) Weg dies zu tun. Mit (u32) kriegst du im Longmode offensichtlich Probleme. Wie gesagt, Portabilität ist keine Eigenschaft einer (Hoch-)Sprache (edit: Aber erst Hochsprachen machen Portabilität möglich, falls jetzt wieder einer der Fließbandjungs kommt und nörgelt), sondern eher eine guten Codes.
Jo, ich habe in meinem Code eh noch jede Menge unportierbare Sachen drin, die ich noch ändern muss, wenn ich demnächst auch ne 64 bit Version haben möchte. Muss eh noch schauen wie genau das dann machbar ist. Evtl. braucht man dann den Präprozessor und solche Sachen? Und natürlich irgendwie ne Angabe ob ich jetzt 32 oder 64 bit compilieren / linken möchte. Ne Makefile bzw. Makefiles wären auch nicht schlecht.  :lol:

bitmaster
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: bluecode am 05. February 2009, 15:34
genau :-) Du hast übrigens meine Frage warum du zu C gewechselt bist nicht beantwortet, obwohl wir deiner Bedingung nachgekommen sind. :-D
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: bitmaster am 05. February 2009, 15:38
...obwohl wir deiner Bedingung nachgekommen sind. :-D
Seid ihr? Uups äh *hust* na ja ...  :-P

bitmaster
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: bitmaster am 05. February 2009, 16:33
Hmm jetzt meckert gcc wieder und ich weiß nicht was ich machen soll. Also ich habe eine Variable Namens blabla vom Typ u32, die einen Wert beinhaltet, der eine Adresse widerspiegelt, die auf einen Null terminierten String zeigt. Aber folgendes mag gcc dann nicht:

strlen(blabla);
und das geht auch net

strlen((u32)blabla);
gcc meckert dann mit:

Zitat
error: passing argument 1 of ‘strlen’ makes pointer from integer without a cast

hmm...

EDIT: arg, ich sollte vielleicht mein bayern fangesang etwas leiser schalten. Es scheint mich wohl doch ein wenig abzulenken. Also so geht es natürlich:

strlen((const char *)blabla);
bitmaster
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: bitmaster am 06. February 2009, 19:25
So, jetzt kann ich im Kernel ja strlen nutzen, indem ich include <string.h> einfüge und ld die libc.a angebe. Das Gleiche bei Anwendungen natürlich auch. Aber dann hängt ja immer die ganze libc an dem Kernel/an den Anwendungen obwohl nur einzelne Funktionen gebraucht werden. Wenn ich z.B. im Kernel nur strlen brauche, dann hätte ich noch x andere Funktionen, die der Kernel gar nicht benötigt. Oder gibt es eine Möglichkeit nicht benötigte Funktionen nicht mit zu linken? Ich könnte in dem Fall natürlich einfach nur die strlen.o mit linken, nur dann würde es sicher eine Fehlermeldung geben, weil die anderen Prototypen, die in der string.h stehen nicht gefunden werden. Von daher stehe ich jetzt doof/unwissend da.  :?

bitmaster
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: bluecode am 06. February 2009, 19:34
Oder gibt es eine Möglichkeit nicht benötigte Funktionen nicht mit zu linken?
Wenn du eine .a mitlinkst, dann nimmt der Linker m.E. aus der .a wirklich nur die Funktionen mit, die du auch verwendest in den anderen Objektdateien (also denen des Kernels selbst).

Zitat
Ich könnte in dem Fall natürlich einfach nur die strlen.o mit linken, nur dann würde es sicher eine Fehlermeldung geben, weil die anderen Prototypen, die in der string.h stehen nicht gefunden werden.
Solange du die anderen Funktionen nicht verwendest wird der Linker nicht meckern, insofern funktioniert deine Lösung mit der strlen.o schon, hat aber natürlich den Nachteil, dass du wahrscheinlich öfter mal deine Makefiles anpassen musst.
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: bitmaster am 06. February 2009, 19:37
 :-o echt? Ja dann, vielen dank. Muss ich gleich mal ausprobieren.

bitmaster
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: bitmaster am 06. February 2009, 19:44
sagt mal, welche Version sollte ich in der string.h stehen haben oder ist das egal?

extern size_t strlen(const char *);
size_t strlen(const char *);
size_t strlen(const char* str);
size_t strlen(const char *str);
thx

bitmaster
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: bluecode am 06. February 2009, 19:46
Zitat
The linker will search an archive only once, at the location where it is specified on the command line. If the archive defines a symbol which was undefined in some object which appeared before the archive on the command line, the linker will include the appropriate file(s) from the archive. However, an undefined symbol in an object appearing later on the command line will not cause the linker to search the archive again.
aus dem Manual (http://sourceware.org/binutils/docs/ld/Options.html#Options) (unter der Option --library=). Bemerkenswert ist, dass die Datei die das undefinierte Symbol enthält dazugenommen wird, nicht nur das Symbol an sich. Also nicht ganz das gleiche wie ich oben behauptet habe.
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: bluecode am 06. February 2009, 19:50
Das sind komplett äquivalente Deklarationen, da zum einen extern implizit verwendet wird, d.h. man bekommt "extern" bei einer Funktionsdeklaration ohne es explizit hinschreiben zu müssen. Die Setzung des Sterns ist eine stylistische Frage und keine semantische (auch wenn es da heiße C vs. C++ Debatten gibt *g*). Das Weglassen des Argumentnamens würde ich aber als unpraktisch ansehen, da man dann zum einen den Parameter nicht über doxygen dokumentieren kann und zum anderen bei modernen IDEs automatisch wenn man zB "strlen(" schreibt einem die Typen und Namen der Parameter angezeigt werden und man am Namen der Parameter gleich erkennt wie die Funktion zu verwenden ist. Beispiel: Wenn ich ein strcpy(char *dest, const char *src) habe und mir wird das angezeigt, dann ist klar(er) von wo nach wo kopiert wird.
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: bitmaster am 06. February 2009, 19:54
ah OK vielen dank, also um noch mal sicher zu gehen, folgendes ist das selbe?

const char *bla
const char* bla
?

bitmaster
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: bluecode am 06. February 2009, 19:55
Ja.
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: bitmaster am 06. February 2009, 20:01
Ja.
Cool danke, jetzt kann ich mir 100%ig sicher sein, dass Bayern Meister wird.  :lol:

bitmaster
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: bitmaster am 07. February 2009, 10:55
So, um wieder dem Thema ziemlich nah zu kommen, habe ich jetzt noch eine Frage bezüglich Strukturen. Sagt mal, was genau ist der Unterschied zwischen:

struct bla
{
...
};

und

typedef struct
{
...
} bla;

vielen dank schon mal

bitmaster
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: Jidder am 07. February 2009, 12:54
Bei ersterem heißt der Datentyp "struct bla" bei zweiterem "bla".
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: bitmaster am 07. February 2009, 13:21
Bei ersterem heißt der Datentyp "struct bla" bei zweiterem "bla".
ah danke

Ist es irgendwie möglich die selbe Funktion mehrmals auszuführen, aber nur eine Zeile zu benutzen? Also dass man

funktion(var1);
funktion(var2);
funktion(var3);

ungefähr so schreiben kann
funktion(var1 kA var2 kA var3);
Also dass man nicht so "hässlich" mehrere Zeilen benötigt um hintereinander die selbe Funktion nur mit verschiedenen Parametern auszuführen. Geht das, oder geht das nicht?

thx

bitmaster
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: bluecode am 07. February 2009, 14:27
Im Allgemeinen nicht. Wenn überhaupt dann über for-Schleife: Wenn i die Zählvariable ist dann kann man entweder den/die Parameter direkt aus i errechnen oder man kann i als Index in ein Array mit den Parameternwerten machen.
also entweder (f ist der Ausdruck mit dem ich von i zu meinem Parameter komm)
for (int i = 0;i < blub;++i)
  func( f(i) );
oder
void func(Type param);
Type A[] = { // Insert my first parameter of type Type here
                     // Insert my second parameter of type Type here
                    ...
                    };
for (int i = 0;i < blub;++i)
  func( A[i] );
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: bitmaster am 07. February 2009, 15:01
hmm.. schade, na ja, nicht sooo schlimm
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: bluecode am 07. February 2009, 15:41
C++0x kann das (zumindest mit einer Hilfsfunktion) :-D

void func_helper(){}

template<typename T, void (*func)(T), typename... Args>
void func_helper(T arg1, Args... pack)
{
  func(arg1);
  func_helper(pack...);
}

das ist eine leicht allgemeinere Lösung als die geforderte, man müsste die auch über
void func(int);
func_helper<int, func>(1, 2, 3, 4, 5, 6, 7); // something like that
aufrufen. Aber ich kenn mich mit variadic templates noch nicht so ganz gut aus und kann da keine Korrektheit garantieren. :-)

edit: Glatt den Basisfall vergessen
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: bitmaster am 12. February 2009, 12:31
So, da bin ich wieder.  :-D

Also ich möchte die Adresse eines Pointers in eine size_t Variable kopieren. Dazu mache ich folgendes:

char *pch;
size_t i;
...
i = pch;

Jetzt meckert gcc mit:

error: assignment makes integer from pointer without a cast

Without a cast? Was heißt das? So geht es nämlich auch nicht:

i = (char *)pch;
Muss ich da irgendwas spezielles machen, oder wie?

thx

bitmaster
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: bluecode am 12. February 2009, 12:48
char *pch;
size_t i;
...
i = (size_t)pch;

Den richtigen Cast verwenden.
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: bitmaster am 12. February 2009, 12:52
char *pch;
size_t i;
...
i = (size_t)pch;

Den richtigen Cast verwenden.
:roll: ich Idiot, thx
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: bitmaster am 17. February 2009, 19:51
Du darfst mit dem sehr wohl rechnen, aber es wird nicht das sein was du dir vorstellst. zB:
T *t = 0;
++t;
Unter der Annahme, dass T ein Typ der Größe s ist, ist nach diesem Codestück t = 0 + 1 * s = s, d.h. es wird anstatt ein Byte weiterzugehen einmal s Bytes weitergegangen.

Wenn du wirklich bytes weitergehen möchtest, dann macht man das so:
T *t = 0;
t = (T*)((uintptr_t)t + x)
wobei x die Anzahl der Bytes ist die du weiter möchtest.
So, ich möchte also jetzt einen Zeiger um z.B. 5 Bytes erhöhen. Dann geht es so ja nicht:

u32 *zeiger;
//<- hier wird der Wert von Zeiger festgelegt
zeiger += 5;

Wenn ich das richtig verstanden habe, würde in diesem Fall Zeiger um 5*32 Bit = 5*4 Bytes = 20 Bytes erhöht, oder?

Will ich aber tatsächlich nur um 5 erhöhen müsste ich es so machen?

zeiger = (u32*)((uintptr_t)zeiger + 5);
Nur leider sagt mir mein gcc

Zitat
error: ‘uintptr_t’ undeclared (first use in this function)

Sprich ich muss uintptr_t erst in der types.h eintragen. Nur als welchen Typen?

thx

bitmaster
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: bluecode am 17. February 2009, 22:27
Wenn ich das richtig verstanden habe, würde in diesem Fall Zeiger um 5*32 Bit = 5*4 Bytes = 20 Bytes erhöht, oder?
ja.

Zitat
Sprich ich muss uintptr_t erst in der types.h eintragen. Nur als welchen Typen?
Kommt offensichtlich auf die Architektur an für die du programmierst. Bei 32bit wohl uint32_t und bei 64bit wohl uint64_t.
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: bitmaster am 18. February 2009, 13:10
Wenn ich das richtig verstanden habe, würde in diesem Fall Zeiger um 5*32 Bit = 5*4 Bytes = 20 Bytes erhöht, oder?
ja.

Zitat
Sprich ich muss uintptr_t erst in der types.h eintragen. Nur als welchen Typen?
Kommt offensichtlich auf die Architektur an für die du programmierst. Bei 32bit wohl uint32_t und bei 64bit wohl uint64_t.
Ah danke. Ich habe aber gesehen dass uintptr_t nicht in die types.h sondern in die stdint.h kommt. Aber wozu brauche ich dann eine types.h, wenn in der stdint.h schon solche Sachen wie int8_t, uint8_t etc. drin stehen? Und wann sollte ich die aus der types.h und wann die aus der stdint.h nehmen? Bzw. wann sollte ich eigentl. generell diese Typen nehmen? Also sollte ich z.B. bei meiner kprint "char *" oder "u8 *" oder "uint8_t *" verwenden?

So, ich habe jetzt noch ein Problem, was nichts mit Programmierung zu tun hat. Ich habe gerade eine Anwendung mittels ./configure und make all install installiert. Nur habe ich diese in dem falschen Verzeichnis installiert. Also ich habe vergessen der ./configure das --prefix=blabla anzugeben. Gibt es eine möglichkeit die Anwendung wieder zu deinstallieren? Also dass er alles rückgängig macht, was ich seit dem ./configure und dem make all install gemacht habe?

thx

bitmaster
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: bluecode am 18. February 2009, 17:36
Ah danke. Ich habe aber gesehen dass uintptr_t nicht in die types.h sondern in die stdint.h kommt. Aber wozu brauche ich dann eine types.h, wenn in der stdint.h schon solche Sachen wie int8_t, uint8_t etc. drin stehen? Und wann sollte ich die aus der types.h und wann die aus der stdint.h nehmen? Bzw. wann sollte ich eigentl. generell diese Typen nehmen? Also sollte ich z.B. bei meiner kprint "char *" oder "u8 *" oder "uint8_t *" verwenden?
Es gibt Standards die dir sagen in welchen Headern welche (Typ-)Definitionen zu finden sind. Einer dieser Standards ist der C99 Standard (bzw. genauer: ISO/IEC 9899:1999, letzter Draft vor der Standardisierung hier (http://open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf)) und ein anderer zu C99 kompatibler Standard wäre beispielsweise die Single UNIX Specification bzw. POSIX (siehe hier (http://www.opengroup.org/onlinepubs/000095399/toc.htm)).
In diesen Standards wird natürlich auch beschrieben was genau für diese Typen garantiert ist, d.h. im Endeffekt was genau man mit diesen Typen machen darf/kann. Was genau du jetzt aber mit "types.h" meinst weiß ich nicht. Ich kenne nur eine "sys/types.h" (nach SUS bzw. POSIX).

Zu "u8": würde ich garnicht verwenden und auch nicht definieren/unterstützen. Es gibt einen Typ (hier uint8_t) nach dem C99 Standard und dann würde ich immer den Typen des Standards nehmen (erhöht Wiederverwendbarkeit und dient dem Verständnis anderer Programmierer).
ansonsten: char* (könnte evtl. mit oder ohne Vorzeichen sein und muss nicht 8Bit sein, gab teilweise auch Archs mit 1Byte = 7, 9 oder 11 Bit afaik) wenn ich von Zeichenketten rede und uint8_t* wenn es mit wichtig ist, dass es sich um Bytes (mit 8Bit) handelt, welche ich ohne Vorzeichen betrachten möchte.
D.h. der Typ spiegelt für mich persönlich auch die Art wie ich ihn verwende wieder.
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: bitmaster am 18. February 2009, 18:48
Ah vielen dank bluecode. Also wenn ich nach dem C99 Standard gehe, dann brauche ich keine types.h sondern verwende die stdint.h (war es glaube ich) und nehme anstatt u8 uint8_t, oder?

Demnach sollte ich meine kprint nicht so

void kprint(char* msg);
sondern lieber so

void kprint(int8_t* msg);
definieren?

thx

bitmaster
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: kevin am 18. February 2009, 19:40
Logisch gesehen gibst du nicht einen Integer aus, sondern Zeichen. Das spräche sehr für char*.
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: bluecode am 19. February 2009, 08:23
Ich wäre ja sehr für ein const dazwischen:
void kprint(const char* msg);
Titel: Re: Struktur auf beliebigen Speicher anwenden
Beitrag von: bitmaster am 21. February 2009, 01:02
So, thx schon mal.

Ich habe folgendes Problem. Ich habe eine Variable vom Typ uint64_t. Jetzt habe ich einen Zeiger und möchte, dass dessen Wert der Adresse gleich dem Wert der Variable ist. Ich mache das so:

uint64_t dummy;
uint8_t* zeiger;
...
zeiger = (uint8_t*)dummy;

Nur da dummy ja Werte größer gleich 4 GByte annehmen kann, gibts unter x86 folgende Meldung von gcc:

Zitat
error: cast to pointer from integer of different size

Wie bringe ich dem gcc jetzt bei, dass der Wert der Variablen dummy zu diesem Zeitpunkt nicht größer gleich 4 GByte ist?

thx

bitmaster

EDIT: Tjo nach dem Posten ist mir die Lösung eingefallen, sry.

So geht es:

zeiger = (uint8_t*)((uintptr_t)dummy);