EXE zu ASM
-
Hi!
Mich beschäftigt, wie ein Diassembler funktioniert. Ist es so, das ein Assembler
(wenn man mal spezifisches wie Strukturen weglässt) die ganzen Mnemonics in
Nummern umwandelt und diese meinetwegen als Byte in die Exe-Datei gespeichert
werden? Als Beispiel MOV hat sagen wir mal die Funktionsnummer 69 und
2 Parameter braucht.MOV 100,200
Somit würde der Assembler MOV in 69 umwandeln, und die 2 Parmater bleiben so:
69 100 200 das ganze sieht dann in Notepad so aus (also in ASCII umgewandelt)
"Ed È "
Also so das die Parameter zusammen immer 4 Byte (da 32-Bit Assembler???) ergeben.
Liege ich da richtig?
Wenn nein, bitte erklährt es mir
Und wenn doch, wo kann ich von den CPU's diese Funktionsnummer herbekommen?
mfg oli
-
Deine Vermutung ist vom Ansatz schonmal richtig.
- Fuer eine Tabelle suche im Internet nach OPCODES.
- Es müssen aber nicht immer 4 Bytes genutzt werden.
- Gleichlautene Befehle haben je nach Parameter unterschiedliche Opcodes
(z.b. Mov mit RegisterByte,AdresseByte einen anderen als Mov mit RegisterWord,AdresseWord)In eine Exe kommen vor die reinen Befehlen z.B. noch die Informationen hinzu, wie und an welche Stelle welche Teile der Datei in den Speicher geladen werden.
Und es wird mitgeteilt, welche Bytes als Befehle und welche als Daten zu interpretieren sind.
-
Hi.
Bei 16/32Bit-Befehlen geht es im Grunde genommen nur um die Verwendung von 16/32Bit Registern/Adressen. Das hat hoechstens indirekt etwas mit der Laenge der OpCodes zu tun.
SeppSchrot schrieb:
Und es wird mitgeteilt, welche Bytes als Befehle und welche als Daten zu interpretieren sind.
Wenn du mit "Bytes" Datenbloecke in der .exe-Datei meinst, kommt das wohl hin.
BTW:
Nur fuer den Fall, dass es nicht klar sein sollte:
"MOV 100,200" funktioniert natuerlich nicht.
-
Danke für die Antworten!
Mit den Datenblock für Exen kann ich ja bei wotsit nachlesen, da sind ja die
Header ganz gut beschrieben.
Das MOV 100,200 nicht geht ist klar, brauchte nur schnell 2 Parameter
Also ist die Bit-Angabe rein für die Regsitergrößen ausgehend?
Dann wollte ich noch fragen, wie überhaupt Register an die Befehle übergeben
werden?
MOV r1,100 wie wird dann der Register r1 umgewandelt? Und wie sieht es mit den
Variablen aus? Die Variablen werden ja in Speicheradressen umgewandelt, aber
es kann ja noch nicht feststehen, wo und wieviel Arbeitspeicher zur verfügung
steht ?oder? werden die Datenblöcke (also da wo man schon vorher den Variablen
konstante Werte übergibt) auch in Exedateien als Datenblöcke übernommen?
mfg olli
-
Vertex schrieb:
Also ist die Bit-Angabe rein für die Regsitergrößen ausgehend?
Diese Aussage stimmt so nicht. Die Adressierung spielt da auch noch eine Rolle. :p
Das ganze ist letztendlich schon ein Eckchen komplizierter:
Als Intel damals mit dem 386 ihre CPU auf 32Bit aufgepumpt hat, gab es da mal wieder das leidige Problem mit der Abwaertskompatibilitaet.
An sich gab es nun alle Befehle, die mit 16Bit-Werten arbeiteten auch noch mal fuer 32Bit. Da wurden dann langsam die OpCodes knapp.
Also wurde hier einmal in die Trickkiste gegriffen und 2Praefix-bytes (66h fuer OpCodes - Verwendung von 32Bit-Registern/Fixwerten etc. und 67h zur Bildung von 32Bit-Adressen) erfunden, die aus einem Befehl, der mit 16Bit-Werten arbeitet (zB. mov ax,bx), einen Befehl machen, der mit 32Bit arbeitet (also 66h + mov ax,bx => mov eax,ebx).Nun wird der Code aber doch ziemlich aufgeblaeht, wenn man auf diese Weise viel mit 32Bit-Befehlen arbeiten will, also gibt es nun praktisch 2 Typen von x86-Code (wird anhand eines Flags im Descriptor eines Segments unterschieden => eigentlich auch nicht so wichtig
) : Einmal den normalen 16Bit-Code, bei dem mit den OpCode-Praefixen 66h/67h 32Bit-Befehle angekuendigt werden und dann den 32Bit-Code, bei dem 66h/67h 16Bit-Befehle ankuendigen.
Vertex schrieb:
Dann wollte ich noch fragen, wie überhaupt Register an die Befehle übergeben
werden?
MOV r1,100 wie wird dann der Register r1 umgewandelt?Bei x86-Codes wird das verwendete Register oft in den OpCode selbst reincodiert.
zB. ist "pop ax" einfach 58h oder "mov ax,0100h" ist B8h (fuer mov ax, %%%%) und dann 0100h. "mov bx,0100h" ist dagegen BBh und 0100h
Ist also unterschiedlich.Vertex schrieb:
Die Variablen werden ja in Speicheradressen umgewandelt...
Die Variablen werden nicht direkt in Speicheradressen umgewandelt.
Die Daten, die du in einer Hochsprache in eine Variable steckst, werden aber mithilfe einer Adresse an einer bestimmten Stelle im Speicher abgelegt. Jede Variable bekommt also beim Compilieren eine bestimmte (Index-)Adresse im Speicher zugewiesen.Vertex schrieb:
..., aber
es kann ja noch nicht feststehen, wo und wieviel Arbeitspeicher zur verfügung
steht ?oder?Das Betriebssystem ist dafuer verantwortlich, deinem Programm freien Speicher zur verfuegung zu stellen. In so fern steht also schon fest, wo wieviel Speicher frei ist.
Die .exe-Datei muss dann vom Betriebssystem in den Speicher geladen werden, dabei werden schonmal die absoluten Adressen der Daten- und Codebloecke festgelegt.
Zur Laufzeit des Programms kann dann vom Betriebssystem auch weiterer Speicher angefordert werden, um zB. Variablen, die erst zur Laufzeit erzeugt werden, unterzubringen.Vertex schrieb:
werden die Datenblöcke (also da wo man schon vorher den Variablen
konstante Werte übergibt) auch in Exedateien als Datenblöcke übernommen?Waere ein logisches Vorgehen, oder?
=> So laeufts (meistens) auch.
-
Zu diesem Thema gibt es ein Tutorial auf:
http://www.iconsoft.de/TUTORIAL/mnemonic.htm
Dort wird ziemlich ausführlich beschrieben wie ein disassembler funktioniert.
-
Das Tutorial ist toll, aber kennt jemand noch ein "weiterführendes" Tutorial, das mehr das hier gepostete beschreibt?
Ich hab nen AMD Duron...
...ich hab nur ne Opcode Tabelle für nen K6 mit MMX gefunden
und da ist halt nur ne Tabelle ohne Erklärung... (ohne Tutorial halt)Danke für Hilfe!
SyL (see you later)
Mirco