2016-10-09 1 views
0

Ich mache ein Klassenprojekt, das ich C-Code nehmen soll, drehe es in x86-64 Assembly und ändere es dann zu Y86. An dieser Stelle soll ich die Summe der Elemente in einer verketteten Liste an Rax zurückgeben. Wenn ich jedoch versuche, den y86-Compiler zu verwenden, wird er nicht angezeigt. Die Y86 Ich machte sah wie folgt aus:Y86 Code - gibt nicht zurück oder zeigt rax

.pos 0 
irmovq Stack,%rsp 
irmovq Stack,%rbp 
jmp Main 

Main: 
     irmovq ele1,%rax 
     pushq %rax 
     call sum_list 
     halt 

sum_list: 
     pushq %rbp 
     rrmovq %rsp,%rbp 
     irmovq $24,%rdx 
     subq %rdx,%rsp 
     irmovq $0,%rdx 
     rmmovq %rdx,-8(%rbp) 
     jmp L2 
L3: 
     mrmovq 24(%rbp),%rax 
     mrmovq (%rax),%rax 
     mrmovq -8(%rbp),%rdx 
     addq %rax,%rdx 
     rmmovq %rdx,-8(%rbp) 
     mrmovq 24(%rbp),%rax 
     mrmovq -8(%rax),%rax 
     rmmovq %rax,24(%rbp) 
L2: 
     irmovq $0,%rcx 
     mrmovq 24(%rbp),%rdx 
     subq %rcx,%rdx 
     jne L3 
     mrmovq -8(%rbp),%rax 
     rrmovq %rbp,%rsp 
     popq %rbp 
     ret 

#linked-list 
.align 8 
ele1: 
     .quad 0x00d 
     .quad ele2 
ele2: 
     .quad 0x0e0 
     .quad ele3 
ele3: 
     .quad 0xf00 
     .quad 0 

.pos 0x500 
Stack: 

Und so rax 0xfed haben sollte, aber in meinem Ergebnis, aber es passiert nichts.

Dies ist der C-Code ich es von bekam:

typedef struct ELE{ 
    long val; 
    struct ELE *next; 
} *list_ptr 

long sum_list(list_ptr ls){ 
    long val = 0; 
    while(ls){ 
    val += ls->val; 
    ls = ls->next; 
    } 
    return val; 
} 
+0

Niemand möchte diese unproduktive Compiler-Ausgabe lesen, die nach jeder Anweisung alles auf dem Stack speichert. Und was meinst du mit "nichts erscheint"? Ein Register hat immer einen Wert, auch wenn es Null ist. Sind Sie sicher, dass Sie das Ergebnis richtig gedruckt haben? Haben Sie sich RAX mit einem Debugger angesehen? –

+0

BTW, normaler Stil in C wäre, eine typedef für die Struktur (kein Zeiger auf die Struktur) zu machen, und dann schreiben Sie "const list_elem * p". Dies macht es offensichtlich, dass es ein Zeiger ist, bevor der Name gelesen wird. Wenn ich 'long sum_list (list_ptr ls)' betrachte, ist mein erster Eindruck, dass es eine Funktion ist, die etwas wertschätzt. (Was technisch stimmt, ein Zeiger hat einen Wert.) –

+0

@PeterCordes Ich benutze yas und yis, um meine Dateien zu kompilieren und auszuführen. Und es zeigt an, wenn Register geändert werden. Es zeigt jedoch nichts über% rax –

Antwort

2

auf dem Code der Suche, so scheint es, dass der Zeiger auf dem Knoten bei 16 (RBP) sein sollte, nicht mehr als 24 (RBP). 0 (rbp) = gespeicherter rbp-Wert, 8 (rbp) = Rücksprungadresse, 16 (rbp) = Zeiger auf Knoten (zur verketteten Liste). Ich sehe nicht, wo die zusätzlichen 8 Bytes auf den Stapel geschoben werden, bevor rbp gespeichert wird.

Das Programm endet mit einer Halteanweisung. Können Sie den Inhalt von Rax bestimmen, wenn dies geschieht (z. B. mit einem Debugger)?

+0

Ich denke, Sie haben Recht, sie verwenden den falschen RBP-Offset. Es wäre sinnvoller, die Funktion arg in RDI zu übergeben (wie das x86-64 SystemV ABI). Ich dachte, diese dumme Menge Code sollte Compiler-Ausgabe sein (offensichtlich von "-O0" anstelle von "-O3")? Das OP sagte, sie verwendeten einen y86-Compiler, also IDK, wie dieser Fehler eingeführt wurde. Wie auch immer, ich sehe den Code RSP - = 24, vielleicht ist das der Ursprung der 24? '16 (% rbp)' sieht für mich richtig aus. Übrigens ist '$ 10' in der Gassyntax nicht '0x10' (ich nehme an, dass y86 gleich ist). Gas AT & T-Syntax verwendet '$' auf sofortige Konstanten. –

+0

Danke! Es funktioniert, nachdem ich die Korrekturen vorgenommen habe. –

+0

Danke für den Kommentar zu $ ​​Immediates. Ich habe das aus meiner Antwort entfernt. Das Subtrahieren von 24 von rsp wirkt sich nicht auf rbp aus, also ist das nicht das Problem. – rcgldr

Verwandte Themen