Autor Thema: Struktur auf beliebigen Speicher anwenden  (Gelesen 38558 mal)

bitmaster

  • Troll
  • Beiträge: 1 138
    • Profil anzeigen
    • OS-64 = 64 Bit Operating System
Gespeichert
« Antwort #40 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
In the Future everyone will need OS-64!!!

FreakyPenguin

  • Administrator
  • Beiträge: 301
    • Profil anzeigen
    • toni.famkaufmann.info
Gespeichert
« Antwort #41 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;

bitmaster

  • Troll
  • Beiträge: 1 138
    • Profil anzeigen
    • OS-64 = 64 Bit Operating System
Gespeichert
« Antwort #42 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
In the Future everyone will need OS-64!!!

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #43 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 an.
« Letzte Änderung: 31. January 2009, 17:05 von bluecode »
lightOS
"Überlegen sie mal 'nen Augenblick, dann lösen sich die ganzen Widersprüche auf. Die Wut wird noch größer, aber die intellektuelle Verwirrung lässt nach.", Georg Schramm

bitmaster

  • Troll
  • Beiträge: 1 138
    • Profil anzeigen
    • OS-64 = 64 Bit Operating System
Gespeichert
« Antwort #44 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 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.
In the Future everyone will need OS-64!!!

bitmaster

  • Troll
  • Beiträge: 1 138
    • Profil anzeigen
    • OS-64 = 64 Bit Operating System
Gespeichert
« Antwort #45 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
In the Future everyone will need OS-64!!!

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #46 am: 31. January 2009, 18:48 »
Ja, du irrst dich. return beendet die Funktion und führt dementsprechend auch den Rücksprung durch.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

bitmaster

  • Troll
  • Beiträge: 1 138
    • Profil anzeigen
    • OS-64 = 64 Bit Operating System
Gespeichert
« Antwort #47 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
« Letzte Änderung: 31. January 2009, 19:00 von bitmaster »
In the Future everyone will need OS-64!!!

Homix

  • Beiträge: 138
    • Profil anzeigen
Gespeichert
« Antwort #48 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

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #49 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
« Letzte Änderung: 31. January 2009, 19:22 von taljeth »
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

bitmaster

  • Troll
  • Beiträge: 1 138
    • Profil anzeigen
    • OS-64 = 64 Bit Operating System
Gespeichert
« Antwort #50 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
« Letzte Änderung: 31. January 2009, 19:26 von bitmaster »
In the Future everyone will need OS-64!!!

Termite

  • Beiträge: 239
    • Profil anzeigen
Gespeichert
« Antwort #51 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;
}

bitmaster

  • Troll
  • Beiträge: 1 138
    • Profil anzeigen
    • OS-64 = 64 Bit Operating System
Gespeichert
« Antwort #52 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*
« Letzte Änderung: 31. January 2009, 19:34 von bitmaster »
In the Future everyone will need OS-64!!!

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #53 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. ;) ]
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #54 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.
lightOS
"Überlegen sie mal 'nen Augenblick, dann lösen sich die ganzen Widersprüche auf. Die Wut wird noch größer, aber die intellektuelle Verwirrung lässt nach.", Georg Schramm

bitmaster

  • Troll
  • Beiträge: 1 138
    • Profil anzeigen
    • OS-64 = 64 Bit Operating System
Gespeichert
« Antwort #55 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
In the Future everyone will need OS-64!!!

bitmaster

  • Troll
  • Beiträge: 1 138
    • Profil anzeigen
    • OS-64 = 64 Bit Operating System
Gespeichert
« Antwort #56 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
In the Future everyone will need OS-64!!!

bitmaster

  • Troll
  • Beiträge: 1 138
    • Profil anzeigen
    • OS-64 = 64 Bit Operating System
Gespeichert
« Antwort #57 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
In the Future everyone will need OS-64!!!

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #58 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.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

bitmaster

  • Troll
  • Beiträge: 1 138
    • Profil anzeigen
    • OS-64 = 64 Bit Operating System
Gespeichert
« Antwort #59 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
In the Future everyone will need OS-64!!!

 

Einloggen