2017-08-29 2 views
3

Ceci est mon programme de montage add.sfonction d'appel d'assemblage de c conduit à la segmentation faute

.globl add 

add: 
    movl 4(%esp), %eax 
    movl 8(%esp), %ebx 
    addl %ebx, %eax 
    ret 

Ceci est mon programme C. J'essaie d'appeler le programme d'assemblage du programme C.

#include <stdio.h> 

int add(int a, int b); 

int main() { 
    int res = add(5,6); 
    printf("%d",res); 
    return 0; 
} 

Mais le code ci-dessus me donne un défaut de segmentation. Quelle est l'origine de cette erreur et comment la réparer?

+2

Si vous créez la même fonction dans C, comment le compilateur de générer du code pour cela? Est-ce qu'il fait une configuration de pile qui vous manque? Est-ce qu'il sauvegarde les registres qu'il utilise pour ne pas les écraser (peut-être sont-ils utilisés ailleurs)? –

+2

Ceci est étiqueté avec 'x86-64'. Si cela est vrai, ce n'est pas ainsi que les arguments sont transmis sur cette architecture dans un ABI dont je suis au courant. Quel est le système d'exploitation et l'architecture sur lesquels cela est compilé? Comment est-il compilé et lié? (L'écrasement se produit probablement parce que la lecture de (% esp) est mauvaise car elle est supposée être% rsp). – Art

+0

Je suis d'accord avec Art. Compilez-vous ceci en code 32 ou 64 bits? –

Répondre

4

En supposant que le cdecl convention d'appel, vous utilisez le registre ebx qui est censé ne pas être mis à mal : sa valeur doit être enregistré, puis restauré par le callee si elle va être modifiée.

L'appelant suppose que ebx ne va pas changer en appelant une fonction. Par conséquent, si le appelé modifie ebx, il doit d'abord le sauvegarder puis le restaurer à sa valeur d'origine avant de revenir de la fonction.


Les registres eax, ecx et edx peut être utilisé sans avoir à les sauver d'abord, puis restauré. Par conséquent, je recommande de remplacer ebx avec edx dans votre code:

add: 
    movl 4(%esp), %eax 
    movl 8(%esp), %edx 
    addl %edx, %eax 
    ret 
+0

Je pensais que 'ebx' est un registre général (lisez-le ici http://www.eecg.toronto.edu/~amza/www.mindsec.com/files/x86regs.html), pourquoi il n'est pas censé être écrasé ? – CIsForCookies

+1

@CIsForCookies il peut être écrasé, mais l'appelant suppose que le registre 'ebx' ne change pas en appelant une fonction, c'est pourquoi l'appelé doit d'abord l'enregistrer puis le restaurer avant de revenir en arrière. –

+0

oh ... ok. Qu'en est-il de 'push ebx' au début de' add'? ça va aller? (évidemment utiliser 'edx' à la place est la bonne façon, mais juste essayer de comprendre) – CIsForCookies