2010-11-24 5 views
9

J'ai suivi l'excellent livre Programming Ground Up, voulant apprendre l'assemblage. Bien que n'étant pas dans le livre à ce stade, je voulais appeler ma fonction d'assemblage de C. sur une machine 32 bits, cela fonctionne comme lorsque vous travaillez à partir du livre.C à assembler convention d'appel 32bit vs 64bit

Ce que je fais ici est de stocker le premier argument en %ebx et le second en %ecx.

.type power, @function 
.globl power 
power: 
    pushq %ebp 
    movl %esp, %ebp 
    subl $4, %esp 

    movl 8(%ebp), %ebx 
    movl 12(%ebp), %ecx 

je compile ce (et le reste de la fonction) dans un fichier objet, créer un main.c, où je prototype la fonction et l'appeler, quelque chose comme ceci:

int power(int b, int x); 
int a = power(2, 1); 

Cependant , quand je compile ceci sur une machine 64 bits, j'obtiens des résultats très inattendus. J'ai modifié l'évidence, comme le fait que %esp et %epb doit être remplacé par %rsp et %rpb, mais creuser avec GDB révèle que les arguments ne sont nulle part sur la pile!

Vérifier ce qu'il se passe en utilisant l'option -S pour GCC Je vois qu'au lieu de pousser les variables sur la pile, GCC stocke les arguments dans les registres.

movl $1, %esi 
movl $2, %edi 
call power 

Sur la machine 32 bits, il fait ce que je pense et pousser les arguments sur la pile:

movl $1, 4(%esp) 
movl $2, (%esp) 
call power 

Maintenant, ce qui se passe ici? Pourquoi GCC passe-t-il les arguments dans les registres sur 64 bits et sur la pile sur 32 bits? C'est très déroutant! Et je ne trouve aucune mention à ce sujet nulle part. Y a-t-il quelqu'un qui peut m'éclairer sur cette situation?

+1

Les conventions d'appel x64 sont différentes des conventions x86. Dans la plupart des cas, en raison des registres supplémentaires, les quatre premiers arguments sont passés dans les registres. – wj32

Répondre

27

64 bits convention d'appel C est:% rdi,% rsi,% RDX,% RCX,% r8 et% r9

Voir la description complète ici: "System V Application Binary Interface: AMD64 Architecture Processor Supplement" http://www.x86-64.org/documentation/abi.pdf

3,2 Fonction Séquence d'appel

Lorsque j'ai appris le même sujet, j'ai créé de petits programmes C avec les fonctions requises, les ai compilés dans un compilateur 64 bits et j'ai lu le code assembleur produit par le compilateur C. Le compilateur C/C++ peut être utilisé comme type de référence d'assembly.

+0

J'ai parcouru ce document précis, mais je l'ai étudié de plus près maintenant, et tout est là, et c'est tout à fait logique maintenant. Merci! – Cbsch

+0

En ce qui concerne votre édition: Oui, c'est comme ça que j'essaie de le faire aussi. La modification de la fonction d'assemblage n'a pas posé de problème, et l'observation de ce que fait le compilateur n'est pas non plus un problème, le problème étant que je ne comprenais pas les règles de ce comportement. Mais le document auquel vous étiez lié était la réponse parfaite pour cela. – Cbsch

+10

En guise de note, Windows utilise un ABI différent - http://msdn.microsoft.com/en-us/library/ms235286.aspx avec seulement RCX, RDX, R8, R9 pour les arguments. – Brian

Questions connexes