C à l'assemblée convention d'appel de 32 bits vs 64 bits

J'ai été à la suite de l'excellent livre de Programmation Sol, le désir d'apprendre de l'assemblée. Bien que n'étant pas dans le livre à ce point, je voulais appeler mon assemblée fonction de C. sur un ordinateur 32 bits, cela fonctionne aussi, c'est quand travailler à partir du livre.

Ce que je fais ici est de stocker le premier argument en %ebx et la deuxième dans %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 cela (et le reste de la fonction) dans un fichier objet, créer un main.c, où j'ai prototype de la fonction et de l'appeler, quelque chose comme ceci:

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

Cependant, quand je compile ce sur un ordinateur 64 bits, j'obtiens des résultats inattendus. J'ai modifié l'évidence, comme le fait que %esp et %epb doit être remplacé par %rsp et %rpb, mais en creusant avec GDB révèle que les arguments sont nulle part pour être trouvée sur la pile!

De vérifier ce qui se passe à l'aide de la -S option de GCC, je peux voir 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 l'ordinateur 32 bits, ça fait ce que j'attends et pousser les arguments sur la pile:

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

Maintenant ce qui se passe ici? Pourquoi ne GCC passer les arguments dans les registres de 64 bits et sur la pile sur 32 bits? C'est très déroutant! Et je ne trouve aucune mention à ce n'importe où. Est ce que quelqu'un peut m'éclairer sur cette situation?

x64 conventions d'appel sont différents pour x86. Dans la plupart des cas, dû à l'apport des registres, les quatre premiers arguments sont passés dans les registres.

OriginalL'auteur Cbsch | 2010-11-24