Opcodes, Mnemonics und deren Gruppierung

DerVonNebenan

Captain Special
Mitglied seit
20.08.2011
Beiträge
233
Renomée
1
Hallo,

ich beziehe mich auf Assembler und auf die Beispiele von https://de.wikibooks.org/wiki/Maschinensprache_i8086/_Was_ist_Maschinensprache.

Ich betreibe z.B. nun 'reverse engineering', und debugge einen Code, welches mit Fortran, C++, oder einer anderen höhren Programmiersprache geschrieben wurde.
Mittels einem debugger lasse ich mir anzeigen, was im Speicher (oder auch Speicheradressen) abläuft ... z.B. (von der oben gelinkten Seite)

0000 FA 33 C0 8E D0 BC 00 7C 8B F4 50 07 50 1F FB FC
0010 BF 00 06 B9 00 01 F2 A5 EA 1D 06 00 00 BE BE 07

Um diesen Assemblercode verstehen zu können, bräuchte ich das CPU Handbuch und eine passende Gruppierung (von der oben gelinkten Seite)

FA
33 C0
8E D0
BC 00 7C
8B F4
50
07
50
1F
FB
FC
BF 00 06
B9 00 01
F2
A5
EA 1D 06 00 00
BE BE 07

Meine Frage wäre nun, wie genau diese Gruppierungen erstellt werden?
... abgesehen von jahrelangen Erfahrungen ;D;D;D

LG
 
Zuletzt bearbeitet:
0000 FA CLI
0001 33C0 XOR AX,AX
0003 8ED0 MOV SS,AX
0005 BC007C MOV SP,7C00
0008 8BF4 MOV SI,SP
000A 50 PUSH AX
000B 07 POP ES
000C 50 PUSH AX
000D 1F POP DS
000E FB STI
000F FC CLD
0010 BF0006 MOV DI,0600
0013 B90001 MOV CX,0100
0016 F2 REPNZ
0017 A5 MOVSW
0018 EA1D060000 JMP 0000:061D
001D BEBE07 MOV SI,07BE
 
Zuletzt bearbeitet:
Das habe ich soweit verstanden ...
Ich meine konkreter, wie ich aus

0000 FA 33 C0 8E D0 BC 00 7C 8B F4 50 07 50 1F FB FC
0010 BF 00 06 B9 00 01 F2 A5 EA 1D 06 00 00 BE BE 07

diese Gruppierung

FA
33 C0
8E D0
BC 00 7C
8B F4
50
07
50
1F
FB
FC
BF 00 06
B9 00 01
F2
A5
EA 1D 06 00 00
BE BE 07

hinbekommen?

Woher weiß ich, dass z.B. 'FA' einzeln steht und '33 C0' zusammengesetzt wird?
Wie kann ein Anfänger diese Codes gruppieren; wie erkennt man, was Programmcode, was Daten, ... sind?
 
siehst Du doch FA ........CLI ist ein 1 Byte Operationscode wenn die CPU den ausführt kommt der nächste Befehl dran
..................... 33 C0...XOR dieser Befehl passt nicht in 1 Byte deshalb nimmt er 2 Byte Platz ein.


usw
 
Zuletzt bearbeitet:
Mehr oder weniger sehe ich da was :D
Das Grundidee dahinter ist mir klar.
Ich muss mir einfach mal ein paar Codes 'auseinandernehmen'.
Hast du spontan ein Buchtitel, wo die ganzen Opcodes und Mnemonics nachzulesen sind?
 
Es muss erstmal nicht unbedingt ein Buch sein, fürs erste tuts:
"AMD64 Architecture Programmer’s Manual Volume 3: General-Purpose and System Instructions", Publication No.24594. Aktuell ist Revision 3.26, May 2018. Es kann aber auch eine asbach-uralt Ausgabe sein; tut hier nichts zur Sache.
Im Appendix A gibt es eine Opcode-Übersicht, Feinheiten sind dann wenn nötig unter der jeweiligen Instruktion nachzulesen.
Vor Beginn des disassemblierens muss die Bit-Basis feststehen, hier im Beispiel sind es 16-Bit (beim assemblieren muss es auch angegeben werden).
Fangen wir mit dem ersten Byte an (alle Werte in Hex): FA. Die Opcode-Liste liefert "CLI" ohne weitere Angaben, also folgt dann nichts weiter. Nächstes Byte: 33; dies liefert "XOR Gv,Ev", also XOR General-Register, General-Register oder Memory. Unter XOR nachgeschaut findet man "XOR reg16, reg/mem16 - 33 /r". Es folgt also auf "33" noch "/r" und dies muss jetzt aufgelöst werden. r steht jetzt für reg16 und reg/mem16. reg ist der 1.Operand (hier ein 16-Bit-Register) und steht codiert wie auch reg/mem16 im r-Byte (nennt sich ModR/M). Dieses Byte ist "C0" und muss binär interpretiert werden -> 11000000. Die Bits 7 und 6 (11) besagen das der 2.Operand (reg/mem16) ein Register ist (00 wäre z.B. eine Speicherstelle). Die Bits 5,4,3 legen den 1. Operanden fest und die Bits 2,1,0 den 2.Operanden. Und "000" ist für 16-Bit das Register "AX" (z.B.001 wäre CX), also lautet die komplette Instruktion "XOR AX,AX". Dann weiter mit "8ED0" usw.
 
Vielen Dank für die ausführliche Anfangserklärung.
Gibt es Tipps für Anfänger, Assembler am Besten zu lernen?
In der Uni nutze ich Fortran für wissenschaftliche Berechnungen
Hier war es so ... 'Augen zu und Sprung ins kalte Wasser'.
 
Ach da fällt mir noch ein , wenn man den Speicherinhalt mit einem Speichermonitor so betrachtet, sollte man bedenken das von einen "Wort" das low Byte zuerst
abgelegt wird und das high Byte dahinter.
Bei 32 Bit bin ich der Meinung ist es auch vertauscht das heisst das low Wort kommt zuerst, danach das high Wort (und die "Wörter" sind natürlich auch vertauscht
so wie oben beschrieben.

das mit dem Speicher sollte man nur so im Hinterkopf haben wenn man mit einem Assembler arbeitet kommt man damit selten in Berührung.

ich würde bei der Anleitung lieber bescheidener Anfangen. LG :)

Am486 Microprocessor Software User's Manual ((von 1994 ;D ) (dann wird der Sprung ins kalte Wasser nicht so hart))
https://support.amd.com/TechDocs/18497.pdf
 
Zuletzt bearbeitet:
Ich verstehe so langsam, warum sich Fortran und Co durchgesetzt haben :D

Code:
DATA SEGMENT WORD 'DATA'
Msg DB 13,10,'Hallo, Welt!',7,13,10,'$'
DATA ENDS
CODE SEGMENT WORD 'CODE'
ASSUME CS:CODE, DS:DATA
Start: mov ax,DATA
mov ds,ax
mov dx,OFFSET Msg
mov ah,009h
int 021h
mov ah,04Ch
int 021h
CODE ENDS
END Start

Nochmal zu einem Klassiker ^^ ...
Mir geht es um die zweite Zeile. Ist hier nicht ein Dreher drin?
'Msg' setzt ein Label. 'DB' entspricht 'Define Byte'. '7', '10' und '13' wären die ASCII-Zeichensätze für 'peep', 'line feed' und 'carriage return'.
Macht das so Sinn, wie es dort oben steht (im Buch wird auf einmal '10' und '13' gedreht)?
Es müsste doch zuerst '13' erfolgen, also Positionierung des Cursor zum Zeilenanfang.
Dann mit '10' der Vorschub de Cursors.

LG
 
Zuletzt bearbeitet:
Du könntest ja mal die 10 und die 13 tauschen.

wenn man allerdings eine mechanische Schreibmaschine nimmt macht sie beides gleichzeitig, das "ping" kam dann zum Schluss.

beim Programmbeispiel muss man sich halt entscheiden was man zuerst nimmt. LG :)
 
Zuletzt bearbeitet:
Meist ist die Reihenfolge von CR und LF in der Praxis egal; wenn die Bildschirm-Ausgabe doch mal komisch aussieht wirds eben im Quell-Text getauscht :) . Was mich mehr "stört" ist die Verwendung von DOS-Beispielen. Ich persönlich denke das im Jahre 2018 dies nichts mehr bringt. Besser wäre die Nutzung eines freien (kostenlosen) Assemblers wie FASM oder NASM usw. und sich die mitgelieferten Beispiele zu Gemüte führen. Dann selbst mal eine kleine 32-Bit-Windows-Exe (16-Bit auch links liegen lassen, 64-Bit kommt dann später) erstellen und schon hat man ein Erfolgserlebnis. Es muss auch nicht unbedingt eine Exe sein.
Eine Buch-Empfehlung kann ich beim besten Willen nicht abgeben; ich habe es irgendwann aufgegeben, nach was Neues zu suchen (gab nichts). Meine vorhandenen Bücher fangen auch alle mit DOS an ;D .
Übrigens, es heißt "Beep", "Peep" gehört in den Hobby-Thread ;D .
 
Fortran gibt es schon ewig, viel Beispiele und Programmieranleitungen beziehen sich noch auf DOS , wenn es hilft die Maschinensprache zu verstehen , würde
ich auf DOS und zb Bios INT ruhig zurückgreifen. Viele alte Bücher sind auch sehr gut und ausführlich beschrieben, die "goldene Zeit" der Maschinensprache lag doch mehr vor dem 21 Jahrhundert. LG :)

Fortran
https://de.wikipedia.org/wiki/Fortran



Nur mal so am Rande

vlt sogar mal ein Grund um einen alten "DOS" Computer zu retten? (frei vom Meltdown und Spectre)
Obwohl ich der Meinung bin das vermutlich der Motorola 68000 zum Verständnis der Maschinensprache besser geeignet ist.

Motorola 68000
https://de.wikipedia.org/wiki/Motorola_68000


Selbst Computer mit einen Power PC Prozessor müssten den Motorola 680xx Code ausfühen können.
Wenn ich mal Zeit und Geld habe werde ich mir so einen mal zum "rumspielen" besorgen.
Was Dir zur Zeit vermutlich nicht viel bringen wird da wohl die meisten Beispiele an der Uni oder FH sich auf den
80x86 PC beziehen nur mal so am Rande halt.

PowerPC
https://de.wikipedia.org/wiki/PowerPC
 
Zuletzt bearbeitet:
Das wäre auch mein Plan ... x86 bzw. dann x64
Die Bücher, welche ich zur Zeit durchblättere sind u.a. aus dem Jahre 1999 ;D
Die 'reiten' halt auf den alten Zeugs rum.

Das Assembler-Buch - Grundlagen und Hochsprachenoptimierung
Das Assembler-Buch - Grundlagen, Einführung und Hochsprachenoptimierung
und ein paar pdfs habe ich mir mal mitgenommen ...
 
Wenn man in das Thema einsteigt ist der "alte Kram" vlt gar nicht mal so schlecht.

Gut das ist zwar ne andere Geschichte aber

mit einen "Taschenrechner" sind Sie ja zum Mond geflogen und sogar gelandet, gut Armstrong musste eingreifen und von Hand landen,
aber mit so einer Rechenleistung würde man heute glatt behaupten eine Flug zum Mond ist mit so einer Rechnenleistung nicht möglich.

im Grossen und Ganzen würde man Heutzutage vermutlich mit ein Bruchteil der heutigen Rechenleistung auskommen und trotzdem fast
alles machen können was heutzutage möglich ist. LG :)
 
Zuletzt bearbeitet:
wird schon irgendwie ...
Wobei die Bücher untereinander auch die Themen und Beispiele unterschiedlich behandeln, was es Anfängern nicht so leicht macht.
Eine Frage zu der Operation: Beispiel.png
Ich habe mir die HexCodes als DezCodes umgewandelt. Ich bekomme jedoch nicht das dort gelistete Ergebis raus.
Was missachte ich bei diesem Beispiel?
 
Ha, der gute alte Podschun (Buchautor)! Hat das DIV-Beispiel von MUL übernommen und vergessen "X" in "/" (oder ":") zu ändern, aber die Resultate sind richtig (die Flags hätte er sich aber sparen können; sind undefiniert).
Fehler kann man eigentlich nur beim Dividenden machen: Entweder du fügst die Words DX und AX zu einem DWord zusammen (dann 06260060hex = 103153760dez) oder DX und AX werden einzeln in Dez umgerechnet und dann addiert. Hier kommts: Der Wert in DX muss dann (vorher) mit 65536 (=2^16) multipliziert werden, es ist ja das High-Word! Also:
0626hex = 1574dez; dies * 65536dez = 103153664dez, dies + 96dez (sind die 60hex) = 103153760dez.
Tipp am Rande: Für den Anfang Hex-Werte immer mit evtl. führenden Nullen der jeweiligen Daten-Größe angeben. Hier z.B. $0060 so lassen und nicht auf $60 reduzieren. Ist ein gern gemachter Fehler!
 
Der obige Link ist schon ziemlich gut. Ergänzend hier noch (freie) Lektüre, die ich hilfreich fand:

Angestaubt, aber evtl. für den Einstieg noch brauchbar:

Günther Born, "Einführung in Assembler" (+ Beispiele) und "MS-DOS Programmierhandbuch"
www-borncity-com/web/Library/EinfASM.pdf
www-borncity-com/web/Library/Source.zip
borncity-com/web/Library/DOSProgHB.PDF

(Die DOS-Interrupts werden heute nix mehr reißen, war aber damals meine "Bibel"... *g*)


Eines der eingängigsten (halbwegs aktuellen) Werke, die ich zu diesem Thema gelesen habe:

Dr. Paul Carter: "Die PC Assemblersprache"
pacman128.github.io/static/pcasm-book-german.pdf

Edit: Weil ich noch keine Links posten darf, bei borncity jeweils "-" mit "." ersetzen...
 
Zuletzt bearbeitet:
Heute nutzt man glaub eher den 'x64dbg'.
Ich finde immer noch krass, dass sämtliche Bücher, welche nach und nach auf x86 und Windows gehen, auf 'alte Kamellen' rumreiten; also sowas wie Win 9x oder Win NT.
Wobei man wohl auch dazu sagen muss, dass ein C64 die Menschheit auf dem Mond brachte ;D
Ich habe vor längerer Zeit gelesesn, dass das komplette Verteidigungnetz von z.B. USA und Osteuropa auf den Relikten des kalten Krieges basieren.

Noch eine kleine Frage bei den logischen Operationen ...
Es wird ein Beispiel gelistet

Code:
or ah, 11111110b ;Setze die Bits 7-1 auf 0, Bit 0 bleibt.
or ax,bx ;AX=AX OR BX

Weitere Infos sind nicht vorhanden. Bei dem ersten Beispiel müsste ich doch im Quellcode vorab via 'mov' einen entsprechenden Wert in das AX-Register laden, damit der 'or' Befehl wie angegeben ausgeführt wird, oder?
 
Zuletzt bearbeitet:
Zurück
Oben Unten