Seite 1 von 3
Disassembler für MIPS-CPUs
Verfasst: Fr 9. Dez 2005, 18:23
von Acade
Damit dieses Thema auch im neuen Board schon mal seinen Aufhänger hat und "suchbar" wird, hier ein paar Links und Keywords dazu:
Original-Thread (nur als "Archiv", bitte nicht weiter dort schreiben):
http://board.topfield.de/viewtopic.php?t=17711
Webpage mit Download und Minimaldoku:
http://acade.au7.de/disasmips.htm
Suchbegriffe, die auf diesen Thread und die obigen Links führen sollen:
Memory-Dump, gcc Object-File, Map-File, HTML-Output, Memory-Referenzen, Symbolische Adressen, ...
Viel Spaß mit disasmips im neuen Board!
Ciao,
Acade
Verfasst: Mo 19. Dez 2005, 12:08
von Harvey
Deine Suchbegriffe führen leider zu keinem Ergebnis.
Ich schätze mal, die Bindestriche sind der Knackpunkt.
Verfasst: Mo 19. Dez 2005, 22:14
von Acade
Danke für den Tip, Harvey. Tja, dann gibt's da also etwas, was man an vB oder den hiesigen Einstellungen noch verbessern kann, unter phpBB geht sowas nämlich (hab's gerade am alten Brett ausprobiert). Du kennst Dich doch eh damit aus, kannst ja Strizzi auch noch einen Tip dazu geben
Ciao,
Acade
Aber sicherheitshalber als vorläufiger Workaround:
Memory Dump, gcc Object File, Map File, HTML Output, Memory Referenzen
MemoryDump, gcc ObjectFile, MapFile, HTMLOutput, MemoryReferenzen
Verfasst: Mo 9. Jan 2006, 17:01
von Strizzi
Hi,
schaut so aus, wie wenn ein Bindestrich als Minus identifiziert wird und somit ein Wildcard ist. Wildcard abzustellen macht aber auch keinen Sinn.
Verfasst: Di 10. Jan 2006, 20:02
von Acade
Hm, wenn der Suchstring ein Minus enthält und dieses als Wildcard interpretiert wird, müsste doch aber ein identischer Zielstring im Beitrag auch gematcht werden, oder? Tut's aber nicht :-((
Egal, ist jetzt auch nicht so wichtig ...
Ciao,
Acade
Verfasst: Di 10. Jan 2006, 20:33
von Strizzi
Hi,
probier bitte noch einmal.
Verfasst: Di 10. Jan 2006, 20:59
von Acade
Na wunderbar, geht doch!
Danke,
Acade
Was hast'n jetzt geändert ;-) ?
Verfasst: Sa 21. Jan 2006, 18:11
von Harvey
Die MIPS-CPU macht mich fertig.
Ich kann ja damit leben, daß grundsätzlich noch der auf einem Sprungbefehl folgende Befehl ausgeführt wird, aber wieso steht dahinter oftmals noch ein zweiter, der augenscheinlich nie ausgeführt wird?
Beispiel (was die Funktion macht weiss ich nicht):
Code: Alles auswählen
0r 001cc154: 3c0f81b2 lui $t7,0x81b2
4r 001cc158: 25ef5bd4 addiu $t7,23508=0x5bd4 # 81b25bd4
8r 001cc15c: 01e47821 addu $t7,$a0
cr 001cc160: 91ef0000 lbu $t7,0($t7)
10r 001cc164: 0004c040 sll $t8,$a0,1
14r 001cc168: 3c1981b2 lui $t9,0x81b2
18r 001cc16c: 000f2c00 sll $a1,$t7,16
1cr 001cc170: 8784a012 lh $a0,-24558($gp)
20r 001cc174: 273965de addiu $t9,26078=0x65de # 81b265de
24r 001cc178: 00052c03 sra $a1,16
28r 001cc17c: 0338c821 addu $t9,$t8
2cr 001cc180: 00a4082a slt $at,$a1,$a0
30r 001cc184: 10200008 beq $at,0,54r
34r 001cc188: 97230000 lhu $v1,0($t9)
38r 001cc18c: 00852023 subu $a0,$a1
3cr 001cc190: a784a012 sh $a0,-24558($gp)
40r 001cc194: 9798a010 lhu $t8,-24560($gp)
44r 001cc198: 00837804 sllv $t7,$v1,$a0
48r 001cc19c: 030fc025 or $t8,$t7
4cr 001cc1a0: 1000002e beq 0,0,108r
50r 001cc1a4: a798a010 sh $t8,-24560($gp)
54r 001cc1a8: 8f999fdc lw $t9,-24612($gp)
58r 001cc1ac: 8f989fe0 lw $t8,-24608($gp)
5cr 001cc1b0: 0338082b sltu $at,$t9,$t8
60r 001cc1b4: 10200027 beq $at,0,100r
64r 001cc1b8: 00001025 move $v0,0
68r 001cc1bc: 00a4c823 subu $t9,$a1,$a0
6cr 001cc1c0: 00192400 sll $a0,$t9,16
70r 001cc1c4: 00042403 sra $a0,16
74r 001cc1c8: 978fa010 lhu $t7,-24560($gp)
78r 001cc1cc: 8f859fd8 lw $a1,-24616($gp)
7cr 001cc1d0: 00837007 srav $t6,$v1,$a0
80r 001cc1d4: 01ee7825 or $t7,$t6
84r 001cc1d8: a0af0000 sb $t7,0($a1)
88r 001cc1dc: 24a50001 addiu $a1,1
8cr 001cc1e0: af859fd8 sw $a1,-24616($gp)
90r 001cc1e4: 8f989fdc lw $t8,-24612($gp)
94r 001cc1e8: 28810008 slti $at,$a0,8
98r 001cc1ec: 27020001 addiu $v0,$t8,1
9cr 001cc1f0: 10200005 beq $at,0,b4r
a0r 001cc1f4: af829fdc sw $v0,-24612($gp)
a4r 001cc1f8: 24190008 move $t9,8
a8r 001cc1fc: 0324c823 subu $t9,$a0
acr 001cc200: 1000000f beq 0,0,ecr
b0r 001cc204: a799a012 sh $t9,-24558($gp)
b4r 001cc208: 8f999fe0 lw $t9,-24608($gp)
b8r 001cc20c: 0059082b sltu $at,$v0,$t9
bcr 001cc210: 50200010 beql $at,0,100r
c0r 001cc214: 00001025 move $v0,0
c4r 001cc218: 2499fff8 addiu $t9,$a0,-8=0xfff8
c8r 001cc21c: 240e0010 move $t6,16=0x0010
ccr 001cc220: 0323c807 srav $t9,$v1,$t9
d0r 001cc224: 24b80001 addiu $t8,$a1,1
d4r 001cc228: 244f0001 addiu $t7,$v0,1
d8r 001cc22c: 01c47023 subu $t6,$a0
dcr 001cc230: a0b90000 sb $t9,0($a1)
e0r 001cc234: af989fd8 sw $t8,-24616($gp)
e4r 001cc238: af8f9fdc sw $t7,-24612($gp)
e8r 001cc23c: a78ea012 sh $t6,-24558($gp)
ecr 001cc240: 9799a012 lhu $t9,-24558($gp)
f0r 001cc244: 0323c804 sllv $t9,$v1,$t9
f4r 001cc248: 10000004 beq 0,0,108r
f8r 001cc24c: a799a010 sh $t9,-24560($gp)
fcr 001cc250: 00001025 move $v0,0
100r 001cc254: 03e00008 jr $ra
104r 001cc258: 00000000 nop
108r 001cc25c: 03e00008 jr $ra
10ar 001cc260: 24020001 move $v0,1
Stein des Anstosses ist die Zeile fcr. Es wird zwar 100r angesprungen, aber niemals fcr. Ich sehe einfach nicht, wie in $v0 eine 0 zurückgegeben werden soll.
Übrigens hat dein Dissassembler (wahrscheinlich aus diesem Grund) aus 104r und 108r eine eigene Funktion gemacht.
Verfasst: Sa 21. Jan 2006, 20:11
von Acade
Hi Harvey,
habe die Stelle im Code gefunden. Der move-Befehl wird tatsächlich nicht angesprungen, das ist toter Code. Der kann von schlechten Compileroptionen kommen, z.B. bei "if (0 != 0) return (0); else return (1);".
Leider kann kein Disassembler ohne Zusatzinfos (z.B. C-Prolog/-Epilog) den Beginn einer neuen Funktion zuverlässig erkennen, daher behilft sich disasmips mit dem vermutlichen Ende einer Funktion, dem "jr $ra"-Befehl. Und der kann beim verwendeten Compiler bzw. dessen Einstellungen auch mitten in einer Funktion vorkommen. Das ist also unvermeidlich.
Kleiner Tip: Du kannst übrigens durch Weglassen der -r-Option von disasmips die absoluten Zieladressen sehen und damit nach Sprungbefehlen auch außerhalb einer durch frühzeitigen "jr $ra"-Befehl beendeten Funktion suchen. Damit kannst Du sicherstellen, daß ein Befehl nicht doch noch von "außerhalb" der Funktion angesprungen wird.
Viel Spaß mit disasmips,
Acade
Edit: 0 wird in $v0 über die Befehle bcr/c0r zurückgegeben, aber das ist Dir ja sicher klar.
Und nicht aus 104r/108r wird eine eigene Funktion, sondern aus 108r/10ar.
Verfasst: Fr 23. Jun 2006, 21:03
von Harvey
Nabbent.
Läge es in der Peripherie der possibalen Globalitäten, die Beschränkung von 100 Zeichen/Zeile aufzuheben oder sagen wir zu verdoppeln?
Alldiweil ich versuche grade, zu übergebenen Variablen im C++-Style zu kommentieren, und das haut absolut nicht hin.
Danke.
Verfasst: Do 29. Jun 2006, 14:57
von Acade
Dein Begehren wurde erhört
Ciao,
Acade
Verfasst: Do 29. Jun 2006, 15:10
von FireBird
Rituale braucht der Mensch: Erster!
Danke.
Verfasst: Do 29. Jun 2006, 17:33
von Harvey
Dankeschön.
Verfasst: Do 29. Jun 2006, 18:14
von Aldarin
Obwohl ich noch blutiger WAA (WiederAsmAnfänger) bin, auch ein kleines Dankeschön von mir
Gruß
Aldarin
Verfasst: Do 29. Jun 2006, 23:32
von Acade
Und von mir immer gerne schöne Grüße nach Austria!
Servus,
Acade
Erkennung von Beginn / Ende von Funktionen
Verfasst: Fr 8. Sep 2006, 23:22
von Acade
Hi,
es gibt eine erhebliche Verbesserung in disasmips, was die Erkennung von Beginn und Ende von Funktionen anbelangt (wichtig für die Angabe von Relativadressen innerhalb von Funktionen und die Aufspaltung des HTML-Outputs in Files an Funktionsgrenzen).
Bisher galt (s. o.):
"Leider kann kein Disassembler ohne Zusatzinfos (z.B. C-Prolog/-Epilog) den Beginn einer neuen Funktion zuverlässig erkennen, daher behilft sich disasmips mit dem vermutlichen Ende einer Funktion, dem "jr $ra"-Befehl. Und der kann beim verwendeten Compiler bzw. dessen Einstellungen auch mitten in einer Funktion vorkommen."
(D.h., die Funktion kann nach einem jr-Befehl auch noch lustig weitergehen.)
Ok, ist richtig und gilt auch weiterhin. Aber: Wenn eine Funktion nach einem jr-Befehl noch weitergeht, muß man irgendwie dorthin kommen können, und das passiert mit (beliebig gearteten) Branch-Befehlen. Also muß man sich nur die Zieladressen aller Branchbefehle einer Funktion ansehen, um zu wissen, wann diese Funktion frühestens zu Ende sein kann und welche jr-Befehle noch mitten in der Funktion liegen müssen. D.h., man kann auf dem Weg zum Funktionsende (das man noch gar nicht kennt) das früheste Funktionsende immer wieder hinausschieben, wenn wieder ein Branchbefehl mit Zieladresse _nach_ dem bisherigen frühesten Ende auftaucht. Auf diese Weise _muß_ man das korrekte Funktionsende finden, sonst hätte der Compiler Code generiert, den man nicht erreichen kann oder es gäbe Branches, die über eine Funktion hinausspringen.
Diese Erkenntnisse habe ich jetzt in disasmips implementiert (Option -F {len}) und als Schutz vor ("falschen") Branch-Befehlen in Datenbereichen, die das früheste Ende der nächsten Funktion auf St.-Nimmerlein verschieben könnten, reicht eine Begrenzung der Reichweite von Branches auf {len} Befehle (default 500, in der Topf-FW voll ausreichend).
Viel Spaß mit der neuen Version von disasmips (Link s.u.)!
Ciao,
Acade
PS: Auf der Webseite ist jetzt auch ein Link zur Benachrichtigung per Email, wenn es eine neue Version gibt, bitte nutzen!
AW: Disassembler für MIPS-CPUs
Verfasst: Sa 9. Sep 2006, 13:19
von Harvey
Sei bedankt.
Falls Du mal Langeweile haben solltest: Hast Du noch eine Idee, Daten mitten in einer Funktion etwas schicker aufzubereiten (relative Adresse)?
Wenn diese Daten vorhanden sind dann sind das (immer?) Sprungtabellen kurz nach einem jr $at .
Ist aber nicht so wichtig.
AW: Disassembler für MIPS-CPUs
Verfasst: Di 12. Sep 2006, 21:56
von Acade
[quote=""Harvey""]
Hast Du noch eine Idee, Daten mitten in einer Funktion etwas schicker aufzubereiten (relative Adresse)?
Wenn diese Daten vorhanden sind dann sind das (immer?) Sprungtabellen kurz nach einem jr $at .
[/quote]
Beispiel? (Ist - Soll)
AW: Disassembler für MIPS-CPUs
Verfasst: Mi 13. Sep 2006, 09:26
von Harvey
ist
Code: Alles auswählen
64r 80005320: 3c018000 lui $at,0x8000
68r 80005324: 24215338 addiu $at,21304=0x5338 # 80005338 -> 8000589c -> 32d90001
6cr 80005328: 00380821 addu $at,$t8
70r 8000532c: 8c210000 lw $at,0($at)
74r 80005330: 00200008 jr $at
78r 80005334: 00000000 nop
7cr 80005338: 8000589c lb 0,22684(0)
80r 8000533c: 8000557c lb 0,21884(0)
84r 80005340: 80005538 lb 0,21816(0)
88r 80005344: 80005378 lb 0,21368(0)
8cr 80005348: 80005514 lb 0,21780(0)
90r 8000534c: 800053e4 lb 0,21476(0)
94r 80005350: 80005418 lb 0,21528(0)
98r 80005354: 800054f0 lb 0,21744(0)
9cr 80005358: 80005444 lb 0,21572(0)
a0r 8000535c: 800054a8 lb 0,21672(0)
a4r 80005360: 800057f0 lb 0,22512(0)
a8r 80005364: 80005800 lb 0,22528(0)
acr 80005368: 80005788 lb 0,22408(0)
b0r 8000536c: 80005820 lb 0,22560(0)
b4r 80005370: 80005830 lb 0,22576(0)
b8r 80005374: 80005858 lb 0,22616(0)
bcr 80005378: 24040032 move $a0,50=0x0032
c0r 8000537c: 0c000499 jal 0x80001264 # sysprocSwitchTask
c4r 80005380: 00000000 nop
c8r 80005384: 8fb80034 lw $t8,52($sp)
soll vielleicht so?
Code: Alles auswählen
64r 80005320: 3c018000 lui $at,0x8000
68r 80005324: 24215338 addiu $at,21304=0x5338 # 80005338 -> 8000589c -> 32d90001
6cr 80005328: 00380821 addu $at,$t8
70r 8000532c: 8c210000 lw $at,0($at)
74r 80005330: 00200008 jr $at
78r 80005334: 00000000 nop
7cr 80005338: 8000589c lb 0,22684(0) #5e0r
80r 8000533c: 8000557c lb 0,21884(0) #2c0r
84r 80005340: 80005538 lb 0,21816(0) usw.
Wenn das zu aufwändig ist lass es.
AW: Disassembler für MIPS-CPUs
Verfasst: Mi 20. Sep 2006, 00:14
von Acade
Hi Harvey,
naja, aufwendig wäre es schon auch, aber kannst Du nicht einfach per Mapfile zu Beginn der Sprungtabelle auf "data representation" umschalten (und am Ende wieder zurück auf Code), etwa so (im Mapfile):
Dann hast Du die Sprungadressen immerhin in absoluter Form. Die relativen Adressen sind sowieso nur für die Branchbefehle eine Erleichterung ...
Ciao,
Acade