C Assemblerprogramm erklären?

Status
Für weitere Antworten geschlossen.

kali-hi

Lieutenant
Registriert
Sep. 2025
Beiträge
696
Hallo, könnte das jemand erklären?

Code:
arr:
        .long   3
        .long   5
        .long   4
        .long   1
        .long   9
        .long   7
        .long   2
        .long   6
        .long   8
n:
        .long   9
iteration:
        push    rbp
        mov     rbp, rsp
        mov     BYTE PTR [rbp-1], 0
        mov     DWORD PTR [rbp-8], 0
        jmp     .L2
.L4:
        mov     eax, DWORD PTR [rbp-8]
        cdqe
        mov     eax, DWORD PTR arr[0+rax*4]
        mov     DWORD PTR [rbp-12], eax
        mov     eax, DWORD PTR [rbp-8]
        add     eax, 1
        cdqe
        mov     eax, DWORD PTR arr[0+rax*4]
        mov     DWORD PTR [rbp-16], eax
        mov     eax, DWORD PTR [rbp-12]
        cmp     eax, DWORD PTR [rbp-16]
        jle     .L3
        mov     eax, DWORD PTR [rbp-8]
        cdqe
        mov     edx, DWORD PTR [rbp-16]
        mov     DWORD PTR arr[0+rax*4], edx
        mov     eax, DWORD PTR [rbp-8]
        add     eax, 1
        cdqe
        mov     edx, DWORD PTR [rbp-12]
        mov     DWORD PTR arr[0+rax*4], edx
        mov     BYTE PTR [rbp-1], 1
.L3:
        add     DWORD PTR [rbp-8], 1
.L2:
        mov     eax, DWORD PTR n[rip]
        sub     eax, 1
        cmp     DWORD PTR [rbp-8], eax
        jl      .L4
        movzx   eax, BYTE PTR [rbp-1]
        pop     rbp
        ret
.LC0:
        .string "%d\n"
print:
        push    rbp
        mov     rbp, rsp
        sub     rsp, 16
        mov     DWORD PTR [rbp-4], 0
        jmp     .L7
.L8:
        mov     eax, DWORD PTR [rbp-4]
        cdqe
        mov     eax, DWORD PTR arr[0+rax*4]
        mov     esi, eax
        mov     edi, OFFSET FLAT:.LC0
        mov     eax, 0
        call    printf
        add     DWORD PTR [rbp-4], 1
.L7:
        mov     eax, DWORD PTR n[rip]
        cmp     DWORD PTR [rbp-4], eax
        jl      .L8
        nop
        nop
        leave
        ret
main:
        push    rbp
        mov     rbp, rsp
        nop
.L10:
        call    iteration
        test    al, al
        jne     .L10
        call    print
        mov     eax, 0
        pop     rbp
        ret

Wieso wird long verwendet und nicht int? Was bedeutet in Z 83 test al, al? Und allgemein, was bedeutet PTR? Ich dachte, in Assembler gibt es nur Register, aber keine Pointer?

Was tut iteration? Wieso gibt es nop und leave?
 
1. Wieso wird .long verwendet und nicht .int?

In GNU Assembler (AT&T-Syntax) sind .long und .int synonym und definieren beide 32-Bit-Ganzzahlen. Die Verwendung von .long ist hier wahrscheinlich eine persönliche Präferenz des Programmierers oder Compilers. Beide Direktiven erzeugen identischen Maschinencode.

2. Bedeutung von test al, al

test al, al prüft, ob das Register al (das niedrigste Byte von rax) den Wert 0 enthält.

Es ist eine effiziente Methode, um auf Null zu prüfen, ohne den Registerwert zu ändern.

In diesem Kontext testet es den Rückgabewert der iteration-Funktion (in al), der angibt, ob während des Durchlaufs Elemente getauscht wurden.

3. Bedeutung von PTR und Pointer in Assembler

PTR in z.B. DWORD PTR ist eine Typangabe für den Speicherzugriff und bedeutet "behandle diese Adresse als Zeiger auf einen 32-Bit-Wert".

Assembler kennt zwar keine Pointer im C-Sinn, aber Speicheradressen werden durch Register + Offset repräsentiert. PTR hilft dem Assembler, die korrekte Speichergröße zu bestimmen.

Beispiel: mov DWORD PTR [rbp-4], eax bedeutet: "Speichere den 32-Bit-Wert aus eax an der Adresse rbp-4".

4. Was tut die iteration-Funktion?

Es ist eine Iteration des Bubble-Sort-Algorithmus:

Vergleicht benachbarte Elemente im Array arr

Tauscht sie, wenn sie in falscher Reihenfolge sind

Setzt ein Flag ([rbp-1]), wenn mindestens ein Tausch stattfand

Gibt das Flag zurück (1 = getauscht, 0 = sortiert)

5. Bedeutung von nop und leave

nop (No Operation): Tut nichts, wird hier wahrscheinlich für Alignment oder als Platzhalter verwendet.

leave: Räumt den Stack-Frame auf und ist äquivalent zu:

asm
mov rsp, rbp ; Stackpointer zurücksetzen
pop rbp ; Alten Basispointer wiederherstellen
Zusammenfassung des Programms:



Hauptfunktion: Ruft iteration wiederholt auf, bis das Array sortiert ist (keine Tausche mehr).

iteration: Ein Durchlauf von Bubble-Sort.

print: Gibt das sortierte Array aus.

Der Code implementiert also Bubble-Sort in Assembler, wobei main die Sortierung durch wiederholte Aufrufe von iteration durchführt.


edit Quelle: Deepseek
 
Zuletzt bearbeitet:
  • Gefällt mir
Reaktionen: Nordwind2000 und kali-hi
  • Gefällt mir
Reaktionen: Bob.Sponge und kali-hi
  • Gefällt mir
Reaktionen: ILoveShooter132, Haggis und madmax2010
@Nordwind2000 Das war Deepseek, nicht ich :D

Für Coding frag ich normalerweise Claude, aber das nutze ich lieber nur für mich, nicht um kontextlose Forenfragen zu beantworten ;)
 
  • Gefällt mir
Reaktionen: BeBur und kuddlmuddl
Metalveteran schrieb:
Das war Deepseek, nicht ich :D
Schade... Dann wäre es schön, wenn man bei so etwas die Quelle anzugeben.

Dachte jetzt gerade... Fachmann... Na ja...
 
  • Gefällt mir
Reaktionen: TomH22 und kali-hi
Vom TE kam ja auch keine Quellenangabe, und er fragt was ein Bubblesort macht.... nun ja.

Hab aber grad ne Quelle hinzugefügt. Will mich ja nicht mit fremden Federn schmücken :)
 
Zuletzt bearbeitet:
ich wusste bislang nur anhand der Ausgabe, dass sortiert wird... nicht, welcher Algo
 
Um herauszufinden wie ein Algorithmus funktioniert, kannst du dir jeden zwischenschritt ausgeben lassen um nachzuvollziehen was passiert
 
  • Gefällt mir
Reaktionen: ILoveShooter132 und kali-hi
kali-hi schrieb:
War es nicht so, dass keine ChatGpt-Antworten gepostet werden sollten?
Ich hab die Forenregeln gerade mal nachgelesen, von KI-Antworten steht da nichts, allerdings:

"Das Fragen nach Lösungen für Hausaufgaben, Übungszettel, Prüfungen etc. Zumindest dann nicht, wenn keine erhebliche Eigenleistung erkennbar ist."

:)
 
  • Gefällt mir
Reaktionen: ILoveShooter132 und TorenAltair
Das ist eher nicht handgeschriebener ASM code btw, sondern Output eines linkers, disasm oder ähnlichem.

Aber das es Bubble sort ist, hätte ich wohl nur erkannt wenn ich Werte protokolliert hätte so wie @madmax2010 beschrieben hat
 
  • Gefällt mir
Reaktionen: kali-hi
Und das PTR gibt es auch nicht in jedem Assembler, selbst wenn der für die selbe Architektur ist. MASM (Microsoft Assembler) und TASM (Borland Turbo Assembler) kennen es beispielsweise und verlangen es in der Regel auch.

NASM kennt es dagegen nicht und würde einen Syntaxfehler erzeugen. Dort geben die eckigen Klammer schon implizit an, dass es eine Adress-Dereferenzierung ist und ein BYTE, DWORD, usw. als Prefix vor dem Klammern gibt die Größe an.
 
  • Gefällt mir
Reaktionen: kali-hi und Metalveteran
Noch eine Frage, wie müsste der Code denn geändert werden, damit das Verfahren stabil ist?

Beispiel:
a b c d e
2 3 1 2 1

Code:
a2 c1 b3 d2 e1
a2 c1 d2 b3 e1
a2 c1 d2 e1 b3
c1 a2 d2 e1 b3
c1 d2 a2 e1 b3
c1 d2 e1 a2 b3
c1 e1 d2 a2 b3

Nach dem Sortieren tritt hier d vor a auf, obwohl beide Elemente gleich sind...
 
Meine Assemblerkenntnisse sind "dezent" eingerostet (seit dem C64 damals nicht mehr benutzt), wozu soll das ganze überhaupt gut sein? Wofür brauchst Du "dringend" eine Sortierfunktion in Assembler, was eine andere Sprache nicht leisten kann, und was hast Du bisher probiert?
 
  • Gefällt mir
Reaktionen: ILoveShooter132
Claude 4.5 sagt:
"
Ich erkläre dir gerne diesen Assembly-Code! Das ist ein Bubble Sort Algorithmus
in x86-64 Assembly.

Zu deinen spezifischen Fragen:

1. Wieso .long statt int?

In Assembly gibt es keine Datentypen wie int - nur Größenangaben:

* .byte = 1 Byte (8 Bit)
* .word = 2 Bytes (16 Bit)
* .long = 4 Bytes (32 Bit)
* .quad = 8 Bytes (64 Bit)

.long entspricht einem 32-Bit Integer (int in C).

2. Was bedeutet test al, al?

test al, al ist ein Trick, um zu prüfen, ob al (das unterste Byte von rax) 0
ist:

* test macht ein bitweises AND und setzt Flags
* al AND al ist nur 0, wenn al = 0 ist
* Danach prüft jne (jump if not equal/zero), ob das Zero-Flag gesetzt ist

Effekt: Wenn die Funktion iteration 0 zurückgibt (kein Swap), endet die
Schleife. Wenn 1 zurückkommt (Swap erfolgt), läuft die Schleife weiter.

3. Was bedeutet PTR?

PTR (Pointer) gibt die Größe des Speicherzugriffs an:

* BYTE PTR = 1 Byte lesen/schreiben
* DWORD PTR = 4 Bytes (Double Word)
* QWORD PTR = 8 Bytes (Quad Word)

Wichtig: In Assembly gibt es Register UND Speicher. PTR zeigt an, dass du auf
Speicher zugreifst, nicht auf Register. Die CPU muss wissen, wie viele Bytes sie
lesen/schreiben soll.

4. Was tut iteration?

Die Funktion macht einen Durchlauf von Bubble Sort:

1. Durchläuft das Array von Index 0 bis n-2
2. Vergleicht arr mit arr[i+1]
3. Wenn arr > arr[i+1]: Tauscht sie
4. Gibt 1 zurück, wenn getauscht wurde, sonst 0

Stack-Layout in iteration:

* [rbp-1] = swapped (1 Byte) - Flag, ob getauscht wurde
* [rbp-8] = i (4 Bytes) - Schleifenzähler
* [rbp-12] = left (4 Bytes) - arr
* [rbp-16] = right (4 Bytes) - arr[i+1]

5. Wieso nop und leave?

nop (No Operation):

* Tut nichts, braucht 1 CPU-Zyklus
* Im main bei Zeile 77: Placeholder für eventuelle Initialisierung (vom Compiler erzeugt)
* Bei Zeile 70 in print: Alignment oder Compiler-Optimierung

leave:

* Kurzform für: mov rsp, rbp ; Stack-Pointer zurücksetzen
pop rbp ; Alten Base-Pointer wiederherstellen
* Räumt den Stack-Frame auf

Gesamtablauf:

main:
→ Ruft iteration auf (ein Durchlauf durch Array)
→ Wenn Tausch erfolgte (al = 1), wiederhole
→ Sonst: Array ist sortiert, rufe print auf

iteration:
→ For i = 0 bis n-2:
Wenn arr > arr[i+1]: Tausche sie
→ Gib zurück, ob getauscht wurde

print:
→ For i = 0 bis n-1:
printf("%d\n", arr)

Das Array [3,5,4,1,9,7,2,6,8] wird sortiert zu [1,2,3,4,5,6,7,8,9] und dann
ausgegeben.

"


macht zumindest auf den ersten Blick Sinn. (ich habe sehr gute Erfahrung mit Claude 4.5 zuumindest in anderen Sprachen und technischen Dingen)
 
  • Gefällt mir
Reaktionen: kali-hi
Tornhoof schrieb:
Das ist eher nicht handgeschriebener ASM code btw, sondern Output eines linkers, disasm oder ähnlichem.
Ja, mich haben auch diese seltsamen nop s usw. gewundert... das würde man doch eher nicht manuell schreiben?
 
@Nilson Okay, das hab ich nicht gesehen, ich dachte, die "normalen" Forenregeln sind vollständig :)

Ändert aber auch nichts daran, dass die Fragen vom TE ziemlich sehr Richtung "Hausaufgabenhilfe" gehen...
 
  • Gefällt mir
Reaktionen: maloz und TorenAltair
Hier ist das Ausgangsprogramm... dies führt auf https://godbolt.org/ genau zu obiger Ausgabe:

C:
#include <stdio.h>

int arr[] = {3,5,4,1,9,7,2,6,8};
int n = 9;

bool iteration() {
    bool result = false;
    int i = 0, a, b;
    while (i < n - 1) {
        a = arr[i];
        b = arr[i+1];
        if (a > b) {
            arr[i] = b;
            arr[i+1] = a;
            result = true;
        }
        i++;
    }
    return result;
}

void print() {
    int i = 0;
    while (i < n) {
        printf("%d\n", arr[i]);
        i++;
    }
}

int main() {
    while (iteration());
    print();
    return 0;
}

@Metalveteran Es ist ja lieb und nett, dass du helfen möchtest, aber die bisherigen Beiträge stören eher, als dass sie nützlich wären.
 
Status
Für weitere Antworten geschlossen.
Zurück
Oben