Add practical boot-sequence analysis example
This commit is contained in:
54
docs/PRACTICAL_EXAMPLE.md
Normal file
54
docs/PRACTICAL_EXAMPLE.md
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
# Praktisches Analyse-Beispiel: ADSP-219x Boot-Sequenz
|
||||||
|
|
||||||
|
In diesem Beispiel analysieren wir einen (generierten) 3-Byte-Packed Dump. Wir gehen die Instruktionen nacheinander durch, wie du es in `iaito` oder mit unserem Disassembler machen würdest.
|
||||||
|
|
||||||
|
## Die Rohdaten (Hex-Dump)
|
||||||
|
```text
|
||||||
|
Offset 0x00: 00 00 00
|
||||||
|
Offset 0x03: 40 12 30
|
||||||
|
Offset 0x06: 50 20 00
|
||||||
|
Offset 0x09: 50 00 14
|
||||||
|
Offset 0x0C: DA 00 00
|
||||||
|
Offset 0x0F: 18 10 0F
|
||||||
|
```
|
||||||
|
|
||||||
|
## Schritt-für-Schritt Disassembly
|
||||||
|
|
||||||
|
### 1. Adresse 0x0000: `0x000000`
|
||||||
|
* **Decodierung:** Type 30 (NOP).
|
||||||
|
* **Bedeutung:** Keine Operation. Oft am Reset-Vektor zu sehen, falls der eigentliche Einsprungpunkt erst bei 0x0004 liegt (je nach Core-Revision).
|
||||||
|
|
||||||
|
### 2. Adresse 0x0001: `0x401230`
|
||||||
|
* **Decodierung:** Type 6 (Immediate Register Load). `0x0123` ist der Wert (4 Bits geshiftet).
|
||||||
|
* **Assembly:** `AX0 = 0x1230`
|
||||||
|
* **Bedeutung:** Das Arithmetische X-Register 0 wird mit einer Konstanten geladen. Das ist der typische Beginn einer Berechnung.
|
||||||
|
|
||||||
|
### 3. Adresse 0x0002: `0x502000`
|
||||||
|
* **Decodierung:** Type 7 (Immediate Address Register Load).
|
||||||
|
* **Assembly:** `I0 = 0x2000`
|
||||||
|
* **Bedeutung:** Ein Index-Register des DAG1 wird mit einer Startadresse geladen. Hier fängt wahrscheinlich ein Daten-Buffer im DM (Data Memory) an.
|
||||||
|
|
||||||
|
### 4. Adresse 0x0003: `0x500014`
|
||||||
|
* **Decodierung:** Type 7.
|
||||||
|
* **Assembly:** `M1 = 1`
|
||||||
|
* **Bedeutung:** Das Modifier-Register wird auf 1 gesetzt. Das bedeutet, bei jedem Zugriff auf den Buffers springt der interne Pointer genau 1 Word weiter.
|
||||||
|
|
||||||
|
### 5. Adresse 0x0004: `0xDA0000` (Multifunktions-Instruction)
|
||||||
|
* **Decodierung:** Type 1. Opcode beginnt mit `11` (Binar: `11 01 101...`).
|
||||||
|
* **Bedeutung:** Hier passiert die Magie. `AMF = 13` (Add), `DMI=0`, `DMM=0`.
|
||||||
|
* **Assembly:** `AR = AX0 + AY0, AX0 = DM(I0 += M0), AY0 = PM(I4 += M4)`
|
||||||
|
* **Schlussfolgerung:** Das ist eine DSP-Operation. Er berechnet die Summe zweier Werte, lädt gleichzeitig den nächsten Wert aus dem Datenspeicher (DM) und gleichzeitig den übernächsten Filter-Koeffizienten aus dem Programmspeicher (PM). **Wenn du das siehst, hast du die Signalverarbeitung gefunden!**
|
||||||
|
|
||||||
|
### 6. Adresse 0x0005: `0x18100F`
|
||||||
|
* **Decodierung:** Type 10 (Direct Jump).
|
||||||
|
* **Assembly:** `JUMP 0x0100`
|
||||||
|
* **Bedeutung:** Ein Sprung zu einer anderen Code-Region (wahrscheinlich das Hauptprogramm oder eine Header-Überspringen).
|
||||||
|
|
||||||
|
## Worauf du achten musst:
|
||||||
|
1. **I/M Paare:** Wenn du siehst, dass `I2` geladen wird, suche nach dem zugehörigen `M2`. Ohne `Mn` kann der DAG nicht sinnvoll inkrementieren.
|
||||||
|
2. **Register-Gruppen:** Der ADSP-2191 hat 4 Gruppen (REG0-3). `AX0` ist REG0, `I0` ist REG1. Wenn du Register-zu-Register Kopien siehst (z.B. `REG(0,4) = REG(1,0)`), achte auf die Gruppennummern im Opcode.
|
||||||
|
3. **B-Bit (Delayed Branches):** Bei Sprüngen (`JUMP`, `CALL`) gibt es oft ein **B-Bit**. Wenn es gesetzt ist (`JUMP (DB)`), wird der Befehl *nach* dem Sprung noch ausgeführt, bevor er springt (Pipelining!). Das ist eine häufige Falle bei Reverse-Engineering.
|
||||||
|
|
||||||
|
---
|
||||||
|
**Nächster Schritt:** Probiere den neuen Disassembler mit dem generierten `base_test.bin` aus:
|
||||||
|
`python3 disassembler/adsp219x_disasm.py testrom/test_roms/base_test.bin`
|
||||||
@@ -14,10 +14,13 @@ def create_rom(filename, format=3):
|
|||||||
"""
|
"""
|
||||||
os.makedirs(os.path.dirname(filename), exist_ok=True)
|
os.makedirs(os.path.dirname(filename), exist_ok=True)
|
||||||
instructions = [
|
instructions = [
|
||||||
TYPE30_NOP, # 0x0000: NOP
|
0x000000, # 0x0000: NOP
|
||||||
TYPE6_AX0 | (0x1234 << 4), # 0x0001: AX0 = 0x1234
|
0x401230 | 0x0, # 0x0001: AX0 = 0x1234 (Type 6, simplified field)
|
||||||
TYPE10_JUMP_ALWAYS | (0x0100 << 4), # 0x0002: JUMP 0x0100
|
0x502000 | 0x0, # 0x0002: I0 = 0x2000 (Type 7)
|
||||||
# ... add more test patterns ...
|
0x500010 | 0x4, # 0x0003: M0 = 1 (Type 7)
|
||||||
|
0xC00000 | (0x13<<13) | (0x0<<11) | (0x0<<8) | (0x0<<2) | (0x0),
|
||||||
|
# 0x0004: X+Y, AX0=DM(I0+=M0), AY0=PM(I4+=M4)
|
||||||
|
0x18010F, # 0x0005: JUMP 0x0100
|
||||||
]
|
]
|
||||||
|
|
||||||
with open(filename, "wb") as f:
|
with open(filename, "wb") as f:
|
||||||
|
|||||||
Reference in New Issue
Block a user