2016-10-09 1 views
0

Je fais un projet de classe que je dois prendre du code C, le tourner dans l'assemblage x86-64 et ensuite le changer en Y86. Un dans ceci je suppose supposer renvoyer la somme des éléments dans une liste liée à rax. Cependant, lorsque j'essaie d'utiliser le compilateur y86, il n'apparaît pas. Le Y86 j'ai fait ressemblait à ceci:Y86 Code - ne pas retourner ou afficher le code

.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: 

Et rax aurait dû 0xfed, mais à mon résultat, rien ne paraît.

Ceci est le code C Je l'ai obtenu de:

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

Personne ne veut lire cette sortie de compilateur non optimisée et mouillée qui stocke tout dans la pile après chaque instruction. Et que veux-tu dire "rien n'apparaît"? Un registre a toujours une valeur, même si c'est zéro. Etes-vous sûr d'avoir correctement imprimé le résultat? Avez-vous regardé RAX avec un débogueur? –

+0

BTW, le style normal dans C serait de faire un typedef pour la structure (pas un pointeur vers la structure), puis écrire 'const_liste_ligne * p'. Cela rend évident que c'est un pointeur avant même de lire le nom. Quand je regarde 'long sum_list (list_ptr ls)', mon impression initiale est que c'est une fonction qui prend quelque chose en valeur. (Ce qui est techniquement vrai, un pointeur a une valeur.) –

+0

@PeterCordes J'utilise yas et yis pour compiler et exécuter mes fichiers. Et cela montre quand les registres sont changés. Cependant, il ne montre rien à propos de% rax –

Répondre

2

En regardant le code, il semble que le pointeur vers le noeud doit être à 16 (RBP), et non 24 (RBP). 0 (rbp) = valeur rbp enregistrée, 8 (rbp) = adresse de retour, 16 (rbp) = pointeur vers le nœud (vers la liste chaînée). Je ne vois pas où les 8 octets supplémentaires sont poussés sur la pile avant que rbp soit sauvegardé.

Le programme se termine par une instruction d'arrêt. Êtes-vous capable de déterminer le contenu de rax lorsque cela se produit (comme l'utilisation d'un débogueur)?

+0

Je pense que vous avez raison, ils utilisent le mauvais offset RBP. Il serait plus logique de passer la fonction arg dans RDI (comme le fait l'ABI x86-64 SystemV). Je pensais que ce stupide désordre de code était censé être la sortie du compilateur (évidemment de '-O0' au lieu de' -O3')? L'OP a dit qu'ils ont utilisé un compilateur y86, donc IDK comment cette erreur a été introduite. Quoi qu'il en soit, je vois le code RSP - = 24, peut-être que c'est de là que vient le 24? '16 (% rbp)' me semble juste. BTW, '$ 10' n'est pas' 0x10' dans la syntaxe de gaz (je suppose que y86 est la même chose). La syntaxe AT & T de gaz utilise '$' sur les constantes immédiates. –

+0

Merci! Cela fonctionne après que j'ai fait les corrections. –

+0

Merci pour le commentaire sur $ immediates. J'ai enlevé cela de ma réponse. En soustrayant 24 de rsp n'affecte pas rbp, ce n'est pas le problème. – rcgldr