Update all docs and test generator to match verified assembler opcodes
- README.md: Complete project overview with plugin status - ARCHITECTURE.md: Fixed register tables (CNTR in REG1, not REG2) - GETTING_STARTED.md: r2-native workflow, removed Python disasm refs - PRACTICAL_EXAMPLE.md: Uses verified open21xx opcodes with bit layouts - ROM_ANALYSIS_WALKTHROUGH.md: Updated format detection and r2 commands - r2plugin/README.md: Simplified, points to assembler test ROM - gen_isa_test.py: All opcodes from open21xx assembler with labels
This commit is contained in:
@@ -1,54 +1,78 @@
|
||||
# Praktisches Analyse-Beispiel: ADSP-219x Boot-Sequenz
|
||||
# Practical Example: Disassembling a Boot Sequence
|
||||
|
||||
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.
|
||||
This walkthrough uses verified opcodes from the open21xx assembler
|
||||
to demonstrate analysis of a typical ADSP-2191 initialization.
|
||||
|
||||
## 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
|
||||
```
|
||||
## Hex Dump (from examples/isa_test.bin)
|
||||
|
||||
## Schritt-für-Schritt Disassembly
|
||||
0x000 000000 NOP
|
||||
0x003 412340 AX0 = 0x1234
|
||||
0x006 456781 AX1 = 0x5678
|
||||
0x009 4AAAA4 AY0 = 0xAAAA
|
||||
0x00C 440002 MX0 = 0x4000
|
||||
0x00F 420006 MY0 = 0x2000
|
||||
0x012 501000 I0 = 0x0100
|
||||
0x015 502001 I1 = 0x0200
|
||||
0x018 303000 I4 = 0x0300
|
||||
|
||||
### 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).
|
||||
## Step-by-Step Analysis
|
||||
|
||||
### 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.
|
||||
### 1. NOP at Reset Vector (0x000000)
|
||||
|
||||
### 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.
|
||||
The processor starts at PM address 0x0000. A NOP here means the
|
||||
real entry point follows immediately, or there is a JUMP to the
|
||||
main code further ahead.
|
||||
|
||||
### 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.
|
||||
### 2. Register Initialization (Type 6: Dreg = Imm16)
|
||||
|
||||
### 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!**
|
||||
0x412340 -> AX0 = 0x1234
|
||||
Bit layout: 01.00.0001.00100.011.0100.0000
|
||||
Bits 23-20 = 0100 (Type 6), bits 3-0 = 0000 (AX0)
|
||||
Immediate value in bits 19-4 = 0x1234
|
||||
|
||||
### 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).
|
||||
### 3. DAG Setup (Type 7: Reg1/Reg2 = Imm16)
|
||||
|
||||
## 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.
|
||||
0x501000 -> I0 = 0x0100
|
||||
Bits 23-20 = 0101 (Type 7, REG1), bits 3-0 = 0000 (I0)
|
||||
|
||||
---
|
||||
**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`
|
||||
0x303000 -> I4 = 0x0300
|
||||
Bits 23-20 = 0011 (Type 7, REG2), bits 3-0 = 0000 (I4)
|
||||
|
||||
This is the classic DAG initialization pattern: set index registers
|
||||
to buffer start addresses, then set modifier and length registers.
|
||||
|
||||
### 4. Compute Instructions (Type 9: ALU/MAC)
|
||||
|
||||
0x22600F -> AR = AX0 + AY0
|
||||
Bits 23-21 = 001, 20-19 = 00 (Type 9)
|
||||
AMF = bits 17-13 = 10011 = X+Y
|
||||
XOP = bits 10-8 = 000 (AX0), YOP = bits 12-11 = 00 (AY0)
|
||||
COND = bits 3-0 = 1111 (TRUE = unconditional)
|
||||
|
||||
0x20800F -> MR = MX0 * MY0 (SS)
|
||||
AMF = bits 17-13 = 00100 = X*Y (SS)
|
||||
|
||||
### 5. Jumps (Type 10 vs 10a)
|
||||
|
||||
Type 10 (conditional, 13-bit address):
|
||||
|
||||
0x180010 -> IF EQ JUMP 0x0001
|
||||
Bits 23-20 = 0001, 19 = 1, 18 = 0 (Type 10)
|
||||
B = bit 17 = 0 (no delay slot)
|
||||
Address = bits 16-4, COND = bits 3-0 = 0000 (EQ)
|
||||
|
||||
Type 10a (unconditional, 16-bit address):
|
||||
|
||||
0x1C0010 -> JUMP 0x0001
|
||||
Bits 23-18 = 000111 (Type 10a)
|
||||
Address = bits 17-4 + bits 1-0 as MSBs
|
||||
S = bit 2 (0=JUMP, 1=CALL), B = bit 3 (delayed branch)
|
||||
|
||||
## Patterns to Look For
|
||||
|
||||
- **FIR/IIR kernels**: Tight DO...UNTIL CE loops containing
|
||||
Type 1 multifunction instructions (MAC + dual memory read).
|
||||
- **Initialization**: Sequences of Type 6/7 loads setting up
|
||||
DAG registers (I/M/L) before entering a processing loop.
|
||||
- **Data tables in PM**: Regions that disassemble as nonsense
|
||||
are likely coefficient tables (24-bit PM data words).
|
||||
|
||||
Reference in New Issue
Block a user