Autor Thema: Globale daten mit nasm?  (Gelesen 7428 mal)

RedEagle

  • Beiträge: 244
    • Profil anzeigen
    • RedEagle-OperatingSystem - Projekt
Gespeichert
« am: 12. February 2008, 12:18 »
Hi
Ich habe folgenden Datenblock:
[global exp_regdump]
exp_regdump:
 rd_eip: dd 0
 rd_eax: dd 0
 rd_ebx: dd 0
 rd_ecx: dd 0
 rd_edx: dd 0
 rd_esp: dd 0
 rd_ebp: dd 0
 rd_esi: dd 0
 rd_edi: dd 0
 rd_eflags: dd 0
 rd_cr0: dd 0
 rd_cr1: dd 0
 rd_cr2: dd 0
 rd_cr3: dd 0
 rd_cr4: dd 0
und folgenden c-code:
DWORD *rptr;
 rptr=exp_regdump;

das Problem: exp_reddump enthält nicht die adresse von rd_eip, sondern den wert.

Wie komme ich an die Adresse dieses blocks??

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #1 am: 12. February 2008, 12:33 »
rptr = &exp_regdump;
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

RedEagle

  • Beiträge: 244
    • Profil anzeigen
    • RedEagle-OperatingSystem - Projekt
Gespeichert
« Antwort #2 am: 12. February 2008, 12:43 »
Danke :)
Aber warum??

bei
name:
 OPcode
enthält name doch auch die Adresse...

FreakyPenguin

  • Administrator
  • Beiträge: 301
    • Profil anzeigen
    • toni.famkaufmann.info
Gespeichert
« Antwort #3 am: 12. February 2008, 12:48 »
Nein, wenn du sowas wie
int a = 42;hast, dann ergibt das in Assembler vielleicht sowas (praktisch gesehen natürlich nicht genau, aber vom sinn her. ;-)):
a:
dd 42

Und mit a greifst du dann auf den Inhalt zu. Mit dem & Zeichen kommst du zu der eigentlichen Adresse des labels.
Es kommt dann natürlich auch noch darauf an, wie du das Label für den C-Compiler deklarierst. Hier wäre das jetzt ein extern int a;

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #4 am: 12. February 2008, 13:16 »
C hat nichts mit Assembler zu tun. Es ist eine eigene Sprache. Man könnte auch die Frage stellen, warum man in Assembler [name] braucht um auf den Inhalt der Variable zuzugreifen.
Ich würde mal sagen man macht es einfach aus Bequemlichkeit, da man bei Variablen meistens den Inhalt und nicht die Adresse braucht. Wäre der Name der Variable die Adresse würde man sich bei der Parameterübergabe auch in den Schwanz beißen, da in C die Parameter (bzw. der Inhalt der Variable) kopiert werden und nicht nur Adressen herumgeschubst.
Wie freaky schon sagte ist der &-Operator dazu da die Adresse einer Variable herauszufinden. Wenn die einen Pointer hast ist der *-Operator dazu da den Inhalt der Variable herzuzaubern (dereferenzieren).
« Letzte Änderung: 12. February 2008, 13:18 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

FreakyPenguin

  • Administrator
  • Beiträge: 301
    • Profil anzeigen
    • toni.famkaufmann.info
Gespeichert
« Antwort #5 am: 12. February 2008, 13:35 »
Man könnte auch die Frage stellen, warum man in Assembler [name] braucht um auf den Inhalt der Variable zuzugreifen.

Deswegen nimmt man ja den Assembler ohne falschrum-Syntax. ;-)
Aber das tut ja hier eigentlich nichts zur Sache. ;-)

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #6 am: 12. February 2008, 20:32 »
Damit es nicht untergeht: Deklaration von exp_regdump im C-Code ist entscheidend.

Wenn du das z.B. so deklarierst:
extern void exp_regdump(); bekommst du die Adresse doch mit rptr = exp_regdump; Besonders toll ist dann, dass &exp_regdump = exp_regdump = *exp_regdump = **exp_regdump = ...

Aber exp_regdump[0] geht trotzdem nicht, denn exp_regdump ist kein Array. Ist doch alles ganz logisch ^^

Noch lustiger ist nur noch extern void (*exp_regdump[])();. Da bekommst du dann die Adresse mit exp_regdump oder &exp_regdump. Den Wert in rd_eip bekommst du mit exp_regdump[0] oder *exp_regdump (was wieder gleich **exp_regdump und so weiter ist.)

C ist ja die einzig wahre Hochsprache und praktisch eine Obermenge von Assembler, wie die dritte Möglichkeit des Auslesens zeigt. Hierbei nutze ich die Kommutativität von Arrayzugriffen aus. Wenn du auf Bezeichner in eckigen Klammern stehst, kommst du an das erste Element (rd_eip) mit 0[exp_regdump] bzw. 0[exp_regdump + 0]. An das zweite Element (rd_eax) kommst du mit 0[exp_regdump + 1], an das dritte mit 0[exp_regdump + 2]. Genial oder? Musst nur beachten, dass du hier nicht wie in Assembler *4 rechnen darfst, sondern das macht der Compiler für dich. Alleine dieses Feature ist schon ein Grund mehr C zu verwenden ;)

Edit: Von extern void (*exp_regdump)(); rate ich übrigens ab. Das ist total unlogisch, denn da ist exp_regdump ungleich &exp_regdump ;) Logischerweise ist extern void (**exp_regdump)(); auch nicht gleich extern void (*exp_regdump[])();.
« Letzte Änderung: 12. February 2008, 20:39 von PorkChicken »
Dieser Text wird unter jedem Beitrag angezeigt.

RedEagle

  • Beiträge: 244
    • Profil anzeigen
    • RedEagle-OperatingSystem - Projekt
Gespeichert
« Antwort #7 am: 12. February 2008, 22:40 »
Vielen dank für die Antworten.

C ist schon ne feine Sprache  :-D

nooooooooos

  • Beiträge: 734
    • Profil anzeigen
Gespeichert
« Antwort #8 am: 12. February 2008, 22:41 »
Ja am liebsten würde ich sie verschlingen und es dabei belassen :-D

Gruss
Noooooooooos

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #9 am: 13. February 2008, 09:55 »
PorkChicken: Du hast da aber einige böse Casts einfach weggelassen, dann ist das doch nur halb so schön :-D
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

 

Einloggen