Assembler Simulieren
-
Hallo,
welchen Simulator brauche ich um folgenden Assembler Code zu simulieren?
movl $0, %edx
movl %eax, -8(%ebp)
movl %edx, -4(%ebp)MfG TheForgotten
-
TheForgotten schrieb:
welchen Simulator brauche ich um folgenden Assembler Code zu simulieren?
Einen der x86-32 Prozessoren Simulieren kann.
-
Kannst du mir da einen empfehlen? Ich habs schon mit ein paar versucht, die haben aber alle probleme und kennen nur "mov" anstatt "movl" ... obowhl das sicher das selbe ist würd ich doch gern nichts am Programm verändern...
-
Hä? Wills du Simulieren welche Bytes der Assembler ausgeben würde, oder was? Oder wills du einfach ne x86-CPU simulieren (dafür z.B. Bochs oder VBox)?
[quote:1d32405c8c="TheForgotten
"]annst du mir da einen empfehlen? Ich habs schon mit ein paar versucht, die haben aber alle probleme und kennen nur "mov" anstatt "movl" ... obowhl das sicher das selbe ist würd ich doch gern nichts am Programm verändern...Das ist jediglich AT&T-Syntax. Viele Assembler (nicht simulatoren) nehmen halt die Intel-Snytax. Aber in Maschinencode ist das das Gleiche.Bitte Beschreib nochmal was ein Assembler-Simulator sein soll, denn ich kapier nicht so recht was du willst.
-
Ich hab nen Code für nen Programm und soll sagen was es macht. Meiner Meinung nach kann es so eigentlich nicht funktionieren, wie es gemacht ist, da es auf die falsche Speicherzelle zugreift ...
Eigentlich soll das Ding die Zahl 5 quadrieren. Mir ist auch noch klar, dass die 5 in eax als auch in den Stack gespeichert wird, bevor square aufgerufen wird. Nur schaut Square dann meiner Meinung nach an der falschen Stelle nach.
Abgelegt wurde die 5 bei (x + 20), es sucht jedoch bei (x +
und liegt damit meiner Meinung nach einfach 12 Felder daneben ...
Daher wollte ich das jetzt simulieren und so erkennen, was genau Sache ist^^
.text square: pushl %ebp movl %esp, %ebp subl $16, %esp movl 8(%ebp), %eax imull 8(%ebp), %eax movl $0, %edx movl %eax, -8(%ebp) movl %edx, -4(%ebp) movl -8(%ebp), %eax movl -4(%ebp), %edx leave ret main: pushl %ebp movl %esp, %ebp andl $-8, %esp subl $24, %esp movl $5, 20(%esp) movl 20(%esp), %eax movl %eax, (%esp) call square movl %eax, 16(%esp) movl $0, %eax leave ret
-
Wenn du das durchgehen möchtest, dann nimm einen Debugger und lass das Programm im Singel-Step-Modus durchlaufen. Dann kannst du den Stack und die Register durchcheken.
-
Und welchen lad ich mir da am besten runter? Ich hab noch null Ahnung von der Sache
-
Ich benutz den Debugger von VisualStudio, da ich in der Regel nur meinen Code debugge und keine externen Programme. Der kann sich aber auch an Prozesse anhängen.
Theoretisch hat Windows auch einen internen Debugger, das CMD-Command "debug". Als externen Debugger gibts z.B. OllyDbg.
-
Danke, danke^^ Jetzt müsst ich nur noch wissen, wie ich aus meinen 20 Zeilen eine *.exe Datei mache?
Wenn ich das bisher mit Programmen ausm Web versucht hab, konnten die immer mit ".text" und mit "leave" nichts anfangen :S
-
Um aus deinem Asm-Code ein Programm zu machen benötigst du Assembler + Linker. Normalerweise würde ich hier auf NASM verweisen, aber der kennt nur seine Intel-Syntax.
Für dich dürfte "as" aus dem GCC-Toolset als Assembler taugen und der "ld" als Linker, welcher ebenfalls beim GCC dabei sind.
-
Ich hab jetzt mal versucht das in intel Code umzuwandeln
.text main: push ebp mov ebp, esp and esp, 8 sub esp, 24 mov [esp+20], 5 mov eax, [esp+20] mov esp, eax call square mov [esp+16], eax mov eax, 0 ; leave ret square: push ebp mov esp, ebp sub esp, 16 mov eax, [ebp+8] imul eax, [ebp+8] mov edx, 0 mov [ebp-8], eax mov [ebp-4], edx mov eax, [ebp-8] mov edx, [ebp-4] ; leave ret
Da wird dann aber ständig Speichterunterlauf/überlauf gemeckert ...
-
Wobei ich eigentlich nur zwei Fragen habe ...
Was macht folgender Teil und brauche ich ihn wirklich?
mov [ebp-8], eax mov [ebp-4], edx mov eax, [ebp-8] mov edx, [ebp-4]
Und, wie kommt die "5" in diese Speicherzelle?
[ebp+8]
Ohne, dass die "5" in dieser Zelle ist, macht
mov eax, [ebp+8]
imul eax, [ebp+8]nämlich keinen Sinn ...
-
Versuch lieber das Original zu verstehen, dir sind da beim Übersetzen anscheinend ein paar Fehler passiert...
-
Beim Original wird ja in
movl $5, 20(%esp)
die 5 auf den Stack gespeichert.
Wie kommt es jetzt, dass man eben diese später über8(%ebp)
erreicht?
Und wofür ist der
movl %eax, -8(%ebp) movl %edx, -4(%ebp) movl -8(%ebp), %eax movl -4(%ebp), %edx
Block ... wird hier einmal in die eine Richtung gespeichert und dann das selbe noch einmal in die andere?
-
; Funktion: int square(int x) pushl %ebp ; stack frame movl %esp, %ebp ; subl $16, %esp ; lokale Variablen (werden nicht benötigt!) movl 8(%ebp), %eax ; eax = Argument = x imull 8(%ebp), %eax ; eax = eax * x = x * x movl $0, %edx ; edx = 0 movl %eax, -8(%ebp) ; Sinnlos movl %edx, -4(%ebp) ; movl -8(%ebp), %eax ; movl -4(%ebp), %edx ; leave ret ; Programmeintritspunkt main: pushl %ebp ; stack frame movl %esp, %ebp ; andl $-8, %esp ; lokale Variablen: align 8 , size = 24 Byte subl $24, %esp ; Auserdem wird hier Platz für das Funktionsargument gemacht (square(int x)) movl $5, 20(%esp) ; Verschwendung -> mov $5,%eax movl 20(%esp), %eax ; movl %eax, (%esp) ; Argument auf den Stack (=5) call square movl %eax, 16(%esp) ; Ergebniss in lokaler Variable speichern movl $0, %eax ; Rückgabewert = 0 leave ret
-
Die 5 wird nicht nur in [esp+20] gespeichert, sondern danach nach eax geschoben und von dort nach [esp]. Dann gibts einen call und ein push, d.h. esp wird um 8 erniedrigt. Dann wird esp nach ebp kopiert und auf [ebp+8] zugegriffen, und das ist natürlich die gleiche Speicherstelle wie die, die vorher mal [esp] war.
Zu der zweiten Frage: Keine Ahnung. Das Programm sieht aus wie von einem Compiler ohne Optimierung erzeugt. Da wird wohl das Ergebnis nochmal in eine lokale Variable geschrieben, obwohl die gar nicht mehr gebraucht wird.
-
Danke, danke^^
-
Wenn's dich interessiert, es dürfte sich dabei um das unoptimierte Kompilat von etwas ähnlichem wie diesem C-Programm handeln:
long long square(int v) { long long ret=v*v; return ret; } int main(void) { int a=5; int s=square(a); return 0; }
-
Man könnte das sinnvollerweise mit dem gas und gdb unter Linux untersuchen, aber gerade um des Verständniswillens würde ich vorschlagen, das ganze mit Bleistift und kariertem Papier(Speicherbereich) aufzuzeichnen.
Dem Stackpointer kann man die Adresse FFFFFFFFh geben, und -8 für den AND-Befehl wäre FFFFFFF8h. Sollte der Stackpointer zufälligerweise auf FEEDDEADh zeigen, dann wird nach dem AND Befehl FEEDDEA8h daraus.