Aliase
Aliase
Laden von Registern
-> mov x0,x1; Ein Alias. Gleiche ist möglich mit add x0, xzr, x1, aber tatsächlich ist es orr x0,xzr,x1
Sourcecode:
mov x1,#100 mov x xzr, x1 mov x1,#300 orr x0,xzr,x1
0000000000000000 <_start>:
0: d2800c81 mov x1, #0x64 // #100 4: aa0103e0 mov x0, x1 8: d2801901 mov x1, #0xc8 // #200 c: 8b0103e0 add x0, xzr, x1 10: d2802581 mov x1, #0x12c // #300 14: aa0103e0 mov x0, x1 18: d2800000 mov x0, #0x0 // #0 1c: d2800ba8 mov x8, #0x5d // #93 20: d4000001 svc #0x0
0,x1
mov x1,#200 add x0,
-> Verwendung von Aliase, um den Code besser zu verstehen, Problem beim debuggen, objdump, da eventuell andere Aliases verwendet werden.
Die von dir beobachtete Diskrepanz resultiert aus dem Unterschied zwischen der **Assembly-Syntax** und der tatsächlichen **Maschinencodierung** sowie der Art und Weise, wie `objdump` und der Assembler die Befehle interpretieren. Lass uns das Schritt für Schritt erklären:
---
- **1. ARM64-Befehlsaliasing**
In ARM64 gibt es viele **Aliase**, d. h. alternative Schreibweisen für denselben Maschinenbefehl. Diese Aliase werden oft verwendet, um die Lesbarkeit des Codes zu verbessern. Beispiele:
- **`MOV x0, x1`** ist ein Alias für **`ORR x0, xzr, x1`**.
- Semantik: Kopiere den Inhalt von `x1` nach `x0`. - Implementierung: Ein logisches OR mit `xzr` (dem Null-Register) ergibt einfach den Wert von `x1`.
- **`ADD x0, xzr, x1`** ist ebenfalls ein Alias für **`ORR x0, xzr, x1`**.
- Semantik: Addiere `x1` zu `xzr` (immer `0`), was effektiv einfach `x1` ist.
---
- **2. Warum wird aus `MOV` oder `ADD` ein `ORR`?**
Die ARM64-Maschinenarchitektur verwendet für mehrere Befehle denselben Opcode. Der tatsächlich verwendete Maschinenbefehl für alle drei (`MOV`, `ADD xzr`, `ORR`) lautet **`ORR`**, da dieser Opcode universell genug ist, um die gewünschten Operationen auszuführen.
Der Assembler interpretiert den Code basierend auf der Absicht des Programmierers: - **`MOV`**: Ein Alias, wird zu einem `ORR` kompiliert. - **`ADD xzr`**: Ein Alias für denselben `ORR`. - **`ORR`**: Der explizite Maschinenbefehl.
---
- **3. Warum zeigt `objdump` wieder `MOV` oder `ADD` an?**
Das Tool `objdump` arbeitet nicht nur auf Maschinencode-Ebene, sondern versucht, den Assembly-Code durch **Rückübersetzung** lesbar zu machen. Dabei: - Entscheidet es sich für die **verständlichste Darstellung**, basierend auf dem Kontext und den Aliases. - Wenn es sieht, dass der Maschinenbefehl einem Alias entspricht (z. B. `ORR x0, xzr, x1`), gibt es ihn möglicherweise als `MOV x0, x1` oder `ADD x0, xzr, x1` zurück.
In deinem Fall: 1. Der Assembler hat den Alias `MOV x0, x1` in den Maschinenbefehl `ORR x0, xzr, x1` kompiliert. 2. `objdump` hat diesen Maschinenbefehl rückübersetzt und **den Alias gewählt, der am besten passt**.
- Hier hat es sich wieder für `MOV x0, x1` oder `ADD x0, xzr, x1` entschieden, obwohl der zugrunde liegende Befehl tatsächlich `ORR` ist.
---
- **4. Warum nicht immer `ORR`?**
Tools wie `objdump` bevorzugen eine lesbare Darstellung: - **`MOV`** ist für Menschen intuitiver als `ORR xzr`. - Der Assembler und Disassembler abstrahieren unnötige Details, um den Code einfacher zu machen.
---
- **Zusammenfassung**
Dein Verständnis ist korrekt: Alle drei Befehle (`MOV`, `ADD xzr`, `ORR`) sind **funktional identisch**. `objdump` wählt jedoch je nach Kontext einen Alias aus, der die Intention des Originalcodes besser widerspiegelt.
Es gibt also keinen Fehler in deiner Beobachtung. Wenn du immer den zugrunde liegenden Maschinenbefehl sehen möchtest, kannst du die Binärdatei mit einem Hex-Editor oder Disassembler auf Opcode-Ebene analysieren. Dort siehst du, dass alle drei als `ORR` codiert sind.