Opcodes aus der Intel-Referenz
-
Hallo,
ich möchte mir zu Lernzwecken einen kleinen Assembler für Intel-Prozessoren schreiben, also habe ich mir die Referenz heruntergeladen. Vor allem interessieren mich die Opcodes für einzelne Befehle, nur leider verstehe ich nicht ganz, wie man die aus der Tabelle ermitteln kann. Zum Beispiel habe ich nach dem Opcode für "push eax" gesucht, aber ich verstehe nicht, wie man den Wert aus der Tabelle ermitteln kann:[b]Opcode[/b] [b]Instruction[/b] [b]Description[/b] FF /6 PUSH r/m16 Push r/m16 FF /6 PUSH r/m32 Push r/m32 50+rw PUSH r16 Push r16 50+rd PUSH r32 Push r32 6A PUSH imm8 Push imm8 68 PUSH imm16 Push imm16 68 PUSH imm32 Push imm32 0E PUSH CS Push CS 16 PUSH SS Push SS 1E PUSH DS Push DS 06 PUSH ES Push ES 0F A0 PUSH FS Push FS 0F A8 PUSH GS Push GS
Ich bedanke mich schonmal recht herzlichen für Antworten!
-
eax ist ein 32-bit register also must du den opcode 50+rd benutzen.
rd ist dabei eine zahl, die das dword register angibt. Dafür müsste in der refenrenz noch eine tabelle stehen. Da eax das erste register ist vermute ich, dass rd=0 --> 50 ist push eax
-
Nur aus dieser Tabelle kannst du das nicht ermitteln.
Schau dich mal weiter in der Referenz um, irgendwo am Anfang muss definiert sein wofuer sowas wie "+rd" oder "r/m16" steht, wie das "instruction format" allgemein aussieht und was zB. ModR/M und SIB bytes sind.Ansonsten weiss ich zwar nicht, wie sicher du auf dem Gebiet Assembler schon bist, aber der x86-Befehlssatz ist vom Aufbau her sicher nicht gerade leichte Kost...
-
Vielen Dank, jetzt hab ich die Tabelle für das Instruction Format gefunden.
-
Ich hab jetzt mal über die Referenz drüber geschaut und da sind ja recht viele Instruktionen aufgeführt. Die meisten werde ich zwar sowieso nicht brauchen (SSE, MMX und so weiter), aber dennoch stellt sich mir die Frage, wie man einen Assembler effizient aufbaut. Ich dachte daran, ihn wie einen Hochsprachen-Compiler zu schreiben, aber während eine Hochsprache ja relativ wenige Keywords und Code-Konstrukte braucht, hat man beim Assembler ein paar hundert Instruktionen. Gibt es da einen speziellen Ansatz, um den Code schnell in Opcodes zu übersetzen?
-
Ich kenne mich zwar beim Compiler-Bau nicht so aus, aber wo liegt denn da das Problem? An einem effizienten Algo zum Identifizieren der Mnemonic-Strings wird es da doch wohl kaum scheitern?
Sonst schau dir halt mal an, wie andere Assembler das machen. Gibt ja genug Open Source (nasm, gas, yasm, ...)
-
Beim Compiler kann man Rekursion nutzen, weil man ja durch Funktionen usw. Struktur in seinen Quelltext bekommt. Bei einem Assemblercode würde das womöglich in so etwas ausarten:
while(!eof) { x = nextline(); switch(x) { case "PUSH EAX": ... case "PUSH EBX": ... case "PUSH ECX": ... ... case "MOV Register, Register": ... case "MOV Register, Speicher": ... case "MOV Register, Register": ... ... } }
Bei PUSH könnte man das noch vereinfachen, aber meistens ist das ja nur durchswitchen durch die verschiedenen Befehle und Kombinationen.
Aber danke für den Tipp mit den Open Source Assemblern. Werde ich mir mal anschauen.
-
Naja...
Das mit dem "Durchswitchen" ist natuerlich reichlich primitiv, da kann man auch durchaus mit mehr Feingefuehl rangehen. Vollkommen unsystematisch ist der x86-Code ja nun auch nicht.
Ansonsten gibt es ja auch durchaus Assembler, die sehr viele Hochsprachenelemente implementieren, wie zB. der MASM.
Mit Rekursion ist da zwar meistens nicht unbedingt geschickt zu arbeiten, aber das duerfte beim Compiler letztendlich ja wohl auch nicht das Ausschlaggebende Mittel beim Programmieren sein...