Erreur de segmentation

yabusame51 Messages postés 2 Date d'inscription lundi 13 décembre 2010 Statut Membre Dernière intervention 15 décembre 2010 - 13 déc. 2010 à 14:38
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

9 réponses

Guilou34 Messages postés 142 Date d'inscription mercredi 5 avril 2006 Statut Membre Dernière intervention 29 janvier 2016 1
13 déc. 2010 à 19:20
Salut
Il manque un Pop Ebx.
0
yabusame51 Messages postés 2 Date d'inscription lundi 13 décembre 2010 Statut Membre Dernière intervention 15 décembre 2010
15 déc. 2010 à 08:16
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
0
Guilou34 Messages postés 142 Date d'inscription mercredi 5 avril 2006 Statut Membre Dernière intervention 29 janvier 2016 1
15 déc. 2010 à 14:08
Il manque aussi un RET pour revenir au Main.
Amicalement
0
cs_patatalo Messages postés 1466 Date d'inscription vendredi 2 janvier 2004 Statut Modérateur Dernière intervention 14 février 2014 2
17 déc. 2010 à 03:36
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.

@++
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
cs_patatalo Messages postés 1466 Date d'inscription vendredi 2 janvier 2004 Statut Modérateur Dernière intervention 14 février 2014 2
17 déc. 2010 à 03:41
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...

@++
0
cs_patatalo Messages postés 1466 Date d'inscription vendredi 2 janvier 2004 Statut Modérateur Dernière intervention 14 février 2014 2
17 déc. 2010 à 03:49
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.

@++
0
cs_patatalo Messages postés 1466 Date d'inscription vendredi 2 janvier 2004 Statut Modérateur Dernière intervention 14 février 2014 2
17 déc. 2010 à 04:02
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.
0
Guilou34 Messages postés 142 Date d'inscription mercredi 5 avril 2006 Statut Membre Dernière intervention 29 janvier 2016 1
17 déc. 2010 à 22:22
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
0
cs_patatalo Messages postés 1466 Date d'inscription vendredi 2 janvier 2004 Statut Modérateur Dernière intervention 14 février 2014 2
18 déc. 2010 à 05:40
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.

@++
0
Rejoignez-nous