Erreur de segmentation

Messages postés
2
Date d'inscription
lundi 13 décembre 2010
Statut
Membre
Dernière intervention
15 décembre 2010
- - Dernière réponse : cs_patatalo
Messages postés
1466
Date d'inscription
vendredi 2 janvier 2004
Statut
Modérateur
Dernière intervention
14 février 2014
- 18 déc. 2010 à 05:40
Bonjour,

Voila je débute en language NASM et j'ai un probleme avec un de mes codes

le voici:

global factor
extern printf


section .text
%define p dword [ebp+8]

factor:
push ebp
mov ebp,esp
mov ebx,2; d<=2

while:
mov edx,0
mov eax,p ; mettre p dans eax
div ebx ;p modulo d
cmp edx,0 ; modulo =0 ? edx=resultat modulo
jne sinon

push ebx
call printf
mov ecx,2
mov eax,p ; mettre p dans eax
div ecx ; p/2 eax=p/2 edx=p%2
cmp p,1 ; p!=1
jne while
sinon:
inc ebx ; d++
cmp p,1 ; p!=1
jne while
fin:
mov esp,ebp
pop ebp



et voici le programme en c pour le tester:

#include <stdio.h>
#include <stdlib.h>

extern void factor(int p);

int main (int n, char *arg[]){
int i;
printf("je suis le super programme %s \n",arg[0]);
for (i=1;i<n;i++){
int p=atoi(arg[i]);
printf("arg[%d]=%d\n",i,p);
factor(p);
}
return 0;
}

Lors de la compilation aucun soucis, mais lors de l'execution il me met une erreur de segmentation... etant debutant j'implore votre aide au plus vite :) merci d'avance
Afficher la suite 

9 réponses

Messages postés
142
Date d'inscription
mercredi 5 avril 2006
Statut
Membre
Dernière intervention
29 janvier 2016
1
0
Merci
Salut
Il manque un Pop Ebx.
Commenter la réponse de Guilou34
Messages postés
2
Date d'inscription
lundi 13 décembre 2010
Statut
Membre
Dernière intervention
15 décembre 2010
0
Merci
Salut, merci pour ton aide. Effectivement il me manque ce Pop ebx, je l'ai rajouté (aprés le call printf).

Mais au moment de retester mon programme plein d'optimisme et de joie à l'idée qu'il fonctionne, ARGH l'erreur est toujours présente
Commenter la réponse de yabusame51
Messages postés
142
Date d'inscription
mercredi 5 avril 2006
Statut
Membre
Dernière intervention
29 janvier 2016
1
0
Merci
Il manque aussi un RET pour revenir au Main.
Amicalement
Commenter la réponse de Guilou34
Messages postés
1466
Date d'inscription
vendredi 2 janvier 2004
Statut
Modérateur
Dernière intervention
14 février 2014
1
0
Merci
salut,

Une division par 2 se fait rarement en asm, on préfère généralement décaler les bits vers la droite. (shr)

le flag carry donnera la valeure du bit éjecté. Ceci devrait déjà te simplifier grandement le code.

@++
Commenter la réponse de cs_patatalo
Messages postés
1466
Date d'inscription
vendredi 2 janvier 2004
Statut
Modérateur
Dernière intervention
14 février 2014
1
0
Merci
erreur de segmentation veut dire acces à une zone de memoire non autorisée.

push ebx
call printf
add esp,1*4; pour remettre la pile à sa place.

Je ne vois pas trop non plus comment tu as codé ta fonction printf. C'est la première que je vois prendre un long en unique parametre...

@++
Commenter la réponse de cs_patatalo
Messages postés
1466
Date d'inscription
vendredi 2 janvier 2004
Statut
Modérateur
Dernière intervention
14 février 2014
1
0
Merci
Dernier petit point:

Sous Windows, les fonctions doivent retourner les registres intactes à l'appelant sauf pour eax, ecx et edx. Ce qui veut dire que tu DOIS sauvegarder et restaurer ebx.

@++
Commenter la réponse de cs_patatalo
Messages postés
1466
Date d'inscription
vendredi 2 janvier 2004
Statut
Modérateur
Dernière intervention
14 février 2014
1
0
Merci
Ce n'etait pas la peine de préciser que tu es débutant, ça se voit comme le nez au milieu de la figure. ;-)

Tu verras, l'assembleur ressemble beaucoup au C. Je ne vois pas trop bien non plus ce qu'est censé faire ta fonction factor.
Commenter la réponse de cs_patatalo
Messages postés
142
Date d'inscription
mercredi 5 avril 2006
Statut
Membre
Dernière intervention
29 janvier 2016
1
0
Merci
Un examen plus approndi montre que l'erreur de segmentation vient d'un mauvais usage de le fonction printf. Celle-ci demande comme arguments l'adresse d'un chaîne de cataractères suivie de la liste des valeurs à imprimer. La chaîne de charactères contient un message éventuel mais surtout le type de chaque valeur.
Le compilateur C connait donc exactement ce qu'il faut empiler avant d'appeler Printf et au retour vide la pile en conséquence.

Voici un example
extern printf ; the C function, to be called

SECTION .data ; Data section, initialized variables

a: dd 5 ; int a=5;
fmt: db "a=%d, eax=%d", 10, 0 ; The printf format, "\n",'0'
SECTION .text ; Code section.

global main ; the standard gcc entry point
main: ; the program label for the entry point
push ebp ; set up stack frame
mov ebp,esp
mov eax, [a] ; put a from store into register
add eax, 2 ; a+2
push eax ; value of a+2
push dword [a] ; value of variable a
push dword fmt ; address of ctrl string
call printf ; Call C function
add esp, 12 ; pop stack 3 push times 4 bytes

mov esp, ebp ; takedown stack frame
pop ebp ; same as "leave" op

mov eax,0 ; normal, no error, return value
ret ; return

Trouvé sur:
http://www.csee.umbc.edu/portal/help/nasm/sample.shtml#printf1

Moi non plus je n'ai pas compris ce que réalise ta fonction et pourquoi utiliser l'assembleur? Si c'est pour une question de vitesse n'est-il pas plus simple d'utiliser l'assemblage en line dans la source C?
Amicalement
Commenter la réponse de Guilou34
Messages postés
1466
Date d'inscription
vendredi 2 janvier 2004
Statut
Modérateur
Dernière intervention
14 février 2014
1
0
Merci
C'est une fonction printf de type unix. Sous windows, la fonction printf est printf(char *buf, const char *fmt, ...) et '\n' correspond à 10,13. (LF, CR)

Windows ne procedant pas directement à un stdout.

@++
Commenter la réponse de cs_patatalo