Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 20/04/2008, à 09:39

dzouille

erreur en assembleur

Bonjour à tous,
d'abord je précise que je suis nouvelle sur le forum et je suis aussi nouvelle à utiliser ubuntu (moins d'un an)...
J'ai taper un petit code en assembleur.
ce programme permet de lire 10 nombres entiers non signés au clavier et écrire dans un fichier resultat les mêmes nombres multipliés par 2. Le fichier résultat doit être crée par le programme et pas par redirection.

global main
section .data

max	db	10
cpt	db	0
deux	db	2
nom	db	"resultat.dat"

section .bss

clav	resb	1
fd	resd	1
section .code
main:
	mov eax,5
	mov ebx,nom
	mov ecx,64
	mov edx,111111111b
	
	mov [fd],eax
	
lecture:
	mov eax,3
	mov ebx,0
	mov ecx,clav
	mov edx,1
	int 80h

	sub byte[clav],'0'

	mov eax,[clav]
	mul BYTE[deux]
	mov [clav],eax
	
	mov eax,4
	mov ebx,[fd]
	mov ecx,[clav]
	mov edx,1
	int 80h	

	mov eax,19	    ;appel système lseek
	mov ebx,[nom]	   ;descripteur de fichier
	mov ecx,2	     ;offset
	mov edx,2	     ;SEEK_CUR
	int 0x80

	inc word[cpt]
	cmp word[cpt],max
	jg lecture

;==== FIN ====
	mov     ebx,0		; argument 0
	mov	eax,1		; appel système N°1 = exit 
	int	80h		; appel système

À la compilation tout va bien,
mais à l'édition des liens ça coince
$ ld ex3.o -o ex3 -e main
ex3.o: In function `lecture':
ex3.asm:(.code+0x89): relocation truncated to fit: R_386_16 against `.data'

Merci d'avance pour votre aide

Hors ligne

#2 Le 20/04/2008, à 17:33

Le Farfadet Spatial

Re : erreur en assembleur

Salut à tous !

   Hé bien ! Ça fait à peu près dix ans que je n'ai pas fait d'assembleur pur... Que de souvenirs...

   Dzouille, lorsque je compile ton programme, j'ai la même erreur chez moi. Est-ce que par hasard ton processeur ne serait pas un 64 bits, de même que ta version d'Ubuntu ? J'ai l'impression que Nasm a du mal avec ce genre d'architecture. Cela dit, je ne suis pas certain que ce soit le fond du problème, mais comme personne ne semble vouloir se préoccuper de toi et que je suis toujours ému par les femmes en détresse, je transmets le court de mes réflexions.

   À bientôt.

                                                                                                          Le Farfadet Spatial

Hors ligne

#3 Le 20/04/2008, à 17:47

dzouille

Re : erreur en assembleur

Bonjour,

J'ai voulu essayer avec un seule nombre. donc on entre un chiffre au clavier, il se multiplie pas 2 et va dans le fichier resultat.dat.
la tout va bien, sauf qu'en ouvrant le fichier resultat.dat j'ai  ^@ qui s'affiche, jamais mon chiffre que j'ai entré au clavier... je comprend pas.
Merci à toi Farfadet de te préoccupé de moi... je désespérais d'avoir une réponse

Dernière modification par dzouille (Le 20/04/2008, à 17:48)

Hors ligne

#4 Le 20/04/2008, à 18:55

Le Farfadet Spatial

Re : erreur en assembleur

Salut à tous !

dzouille a écrit :

J'ai voulu essayer avec un seule nombre. donc on entre un chiffre au clavier, il se multiplie pas 2 et va dans le fichier resultat.dat.
la tout va bien, sauf qu'en ouvrant le fichier resultat.dat j'ai  ^@ qui s'affiche, jamais mon chiffre que j'ai entré au clavier... je comprend pas.

C'est tout à fait normal, puisque tu inscrits la valeur saisie et non pas son code ascii/utf8. A minima, si la valeur ne fait qu'un seul caractère, il faut lui ajouter la valeur du caractère '0'. S'il y a plus d'un caractère, il faut prendre le reste de la division par dix, ajouter '0' et l'écrire dans le fichier, puis diviser la valeur par dix et recommencer, jusqu'à n'avoir plus que zéro.

   À bientôt.

                                                                                                                                                Le Farfadet Spatial

Hors ligne

#5 Le 20/04/2008, à 19:07

dzouille

Re : erreur en assembleur

Je le fais.
Je commence par lire au clavier, je met le contenu de ce que j'ai lu dans eax, je lui ajoute '0'. je multiplie le contenu de eax par 2, je retransfère la valeur dans ma variable. Et je l'envoie dans mon fichier. (en considérant qu'a chaque je n'entre qu'un chiffre au clavier)
Ça me semble correct comme logique.. enfin sans doute que non, puisque je n'ai que ce caractère qui va dans mon fichier.

Merci

Hors ligne

#6 Le 20/04/2008, à 19:45

Le Farfadet Spatial

Re : erreur en assembleur

Salut à tous !

   Heu... Je n'ai pas vu ça dans ton code source, mais il me semble que tu l'as quelque peu modifié. Donc, plutôt que de demander de l'aide dans le vide, pourquoi ne donnes-tu pas la version actuelle ?

   Sinon, je me demande pourquoi tu multiplies par 2, il doit y avoir un truc qui m'échappe...

   À bientôt.

                                                                                                          Le Farfadet Spatial

Hors ligne

#7 Le 20/04/2008, à 19:54

dzouille

Re : erreur en assembleur

Je multiplie par deux car: ... et écrire dans un fichier resultat les mêmes nombres multipliés par 2.... Donc dans mon fichier resultat je renvoie le nombre entré au clavier multiplier par 2.
ok, je renvoie mon code

global main
;==============
section .data
;==============
max    db    10
cpt    db    0
deux    db    2
nom    db    "resultat.dat"
;==============
section .bss
;==============
clav    resb    1
fd    resd    1
;=============
section .text
;=============
main:

mov eax,5
mov ebx,nom
mov ecx,64
OR ecx,1
mov edx, 111111111b
int 80h

mov [fd],eax

; lecture au clavier
lecture:
mov eax,3
mov ebx,0
mov ecx,clav
mov edx,1
int 80h

mov eax,[clav]
add eax,'0'

mul BYTE[deux]
mov [clav],eax

;add BYTE[clav],'0'

mov eax,19
mov ebx,[nom]    ;descripteur de fichier
mov ecx,2    ;offset
mov edx,1    ;SEEK_CUR
int 0x80

mov eax,4
mov ebx,[fd]
mov ecx,[clav]
mov edx,1
int 80h

;inc word[cpt]
;cmp word[cpt],max
;jg lecture

fin:
mov eax, 1
mov ebx, 0
int 80h

Voici mon nouveau code,il n'y a pas énormément de modification...

Hors ligne

#8 Le 23/04/2008, à 15:30

Ultandir

Re : erreur en assembleur

Bonjour,

Avec ce nouveau script, toujours la même erreur? ( je ne peut pas compiler actuellement mais c'est pour savoir si l'erreur de compilation est toujours une piste ou si c'en est devnu une autre.. )


Fedora Cambridge i386
Zenwalk 5.2
-------------
Il y a 10 types de personnes : celles qui connaissent le binaire, et celles qui ne le connaissent pas.

Hors ligne

#9 Le 23/04/2008, à 15:40

Le Farfadet Spatial

Re : erreur en assembleur

Salut à tous !

Ultandir a écrit :

Avec ce nouveau script, toujours la même erreur?

En assembleur, on ne parle pas trop de script, plutôt de programme et pas vraiment de compilation non plus, plutôt d'assemblage --- oui, je suis tatillon.

   Cela dit, non, il me semble que le problème de dzouille, maintenant, c'est que ce qui est écrit dans le fichier ne correspond pas à ce qu'elle tape au clavier. Je dois admettre que je n'ai pas pris le temps de regarder ça chez moi.

   À bientôt.

                                                                                                                         Le Farfadet Spatial

Hors ligne

#10 Le 23/04/2008, à 17:44

Ultandir

Re : erreur en assembleur

Autant pour moi pour les noms, je n'ai plus l'habitude d'écrire en assembleur.

Sinon, ce qui me gène dans son script, c'est que ces "mov" n'indiquent pas du tout combien elle déplace.
Je m'explique.
On ne sait pas si elle déplace un long, un short, un byte....

Rajouter la lettre correspondante ( movl....) pourrait fixer la chose.
Ca me parait fort que le problème vienne de la mais bon, si le programme prend un byte au lieu d'un long et qu'il tronque le code binaire, ca peut donner de droles de choses big_smile

@Dzouille : A tu fait exprès de choisir ces registres précis; (%eax, %ebx, %ecx....)  ou les a tu pris par défaut?
Si tu manipule de petites valeurs, ne serait il pas plus sage de prendre des "sous-registres" (%al, %ah si ma mémoire est bonne...)

Sinon ca fait du bien de voir que certaines personnes s'interessent à l'assembleur, je commencait à desesperer et à croire que je suis vraiment cinglé comme le disent les personnes a qui je dit que j'aime l'assembleur big_smile


Fedora Cambridge i386
Zenwalk 5.2
-------------
Il y a 10 types de personnes : celles qui connaissent le binaire, et celles qui ne le connaissent pas.

Hors ligne

#11 Le 23/04/2008, à 19:11

dzouille

Re : erreur en assembleur

Ultandir, je choisi eax, ebx,... car je dois pouvoir allé jusqu'à la valeur 1000000000.
et avec ces registre la j'ai la possibilité d'allé jusqu'à 4000000000 et un peu plus...
Sinon, je vous remercie, j'y ai passer toute la soirée et j'ai changer pas mal de chose, quasiment tout enfait, et j'obtient enfin ce que je voulais au départ. je passe par un tableau qui reçois les 10nb entré au clavier, il les multiplie et les envoie dans un fichier resultat.dat...
ca tourne à merveille, je vous envoie le code si ca vous interesse.
Il ya egalement pas mal de commentaires. Voila, encore merci à vous

global main



;========================================================

section .data

nombre        dd     0

nom     db    "resultat.dat",0

espace         db    ' '
deux        db    2

;========================================================

section .bss

hFichier    resd    1

clav        resb    10

bufferInv    resb    10

tabNombres    resd    10

;========================================================

section .code


main:
    call boucle                ; rempli le tableau avec les chiffre multiplier par deux.
    call ouverture                ; ouvre le fichier resultat.dat
    call ecritureFichier            ; tranforme chaque nb du tableau en caractere pour les afficher, si == 0(null) ecris un espace pour le                             ; nombre suivant.
    call fermeture                ; referme le fichier
    call fin                ; fin du programme

;--- remplir le tableau ---

    mov ECX, 0                 ;Indice de deplacement dans le tableau et compteur

boucle:

    push ECX
    call lectureClavier

    pop ECX

   

    call caracToBin                ;conversion vers Binaire



    mov EAX, [nombre]
    shl EAX,1                    ; nombre contient le nombre lu
    ;mul BYTE[deux]                ; multiplie ce nombre par deux

    mov [tabNombres + ECX * 4], EAX        ; case ECX du tableau reçois le nombre

    inc ECX                    ; incrémente le compteur

    cmp ECX, 10                ; si il a lu les 10 nombres

    jne boucle                ; si non recommence avec le nombre suivant

    ret


;--- ouverture du fichier ---
ouverture:

    mov EAX, 5

    mov EBX, nom

    mov ECX, 001000000b            ; O_CREATE

    or  ECX, 01b                ; O_WRONLY

    mov EDX, 110110110b             ; droits

    int 80h                 ; création du fichier

    mov [hFichier], EAX

    ret
   

;--- Ecriture du Fichier ---
ecritureFichier:

    mov EBX, 0                 ;EBX sert d'indice de deplacement dans le tableau



    boucleTab:

        mov EAX, [tabNombres + EBX * 4]    ; EAX reçois le 1e nombre du tableau

        mov [nombre], EAX        ; le met dans nombre

        call BinToCarac            ; le transforme en caractère pour pouvoir l'afficher



        mov ECX,clav           

        .boucleEcrire:            ; ecris le nombre

            call ecrire

            inc ECX



            cmp BYTE [ECX], 0

            jne .boucleEcrire



        mov ECX, espace            ; fin d'un nb, met un espace

        call ecrire



        inc EBX                ; pour passer à l'élément suivant du tableau

        cmp EBX, 10            ; 10 élément = fin

        jne boucleTab

    ret


;--- Fermeture du fichier ---
fermeture:

    mov EAX,6

    mov EBX,[hFichier]

    int 80h        

    ret

;--- lecture au clavier ---

lectureClavier:



    pusha



    mov EAX, 3

    mov EBX, 0

    mov ECX, clav

    mov EDX, 10

    int 80h



    popa

    ret


;--- ecriture ---

ecrire:

    push EAX

    push EBX

    push EDX



    mov EAX, 4

    mov EBX, [hFichier]

    mov EDX, 1

    int 80h



    pop EDX

    pop EBX

    pop EAX

    ret


;--- le caractère en binaire ---

caracToBin:

    ;Calcul la longueur du nombre

    pusha

    mov EAX, 0

    .longueur:

        cmp BYTE [clav + EAX], 10         ; Line Feed = 10 (enter)

        je .finLongueur

        inc EAX                 ; incrémente EAX à chaque caractère(EAX contiendra le nombre de caractères entrés)

        jmp .longueur



    .finLongueur:



    mov EDX, 0

    mov DWORD [nombre], 0

    mov ECX,EAX

    mov EBX, 1

    .bouclecaracToBin:

        dec ECX

   

        mov EAX, 0

        mov AL,[clav + ECX]

        sub AL, '0'

        mul EBX

        add DWORD [nombre], EAX



        mov EAX, EBX

        mov EBX, 10

        mul EBX

        mov EBX, EAX



        cmp ECX, 0

    jne .bouclecaracToBin



    popa

    ret


;--- le binaire en caractère ---

BinToCarac:

    pusha



    mov ECX, 0

    mov EAX, [nombre]

    .boucleBinToStr:

        xor EDX, EDX

        mov EBX, 10

        div EBX

   

        add DL, '0'

        mov [bufferInv + ECX], DL

        inc ECX

        cmp EAX, 0

    jne .boucleBinToStr



   

    dec ECX

    xor EDX, EDX

.retournement:

    mov al, [bufferInv + ECX]

    mov [clav+EDX], al

    inc EDX

    dec ECX

   jns .retournement

    mov byte [clav+EDX],0



    popa

    ret


;--- épilogue ---
fin:


    mov EAX,1

    mov EBX,0

    int 80h

Hors ligne

#12 Le 24/04/2008, à 07:01

Ultandir

Re : erreur en assembleur

Merci beaucoup à toi de partager ton travail en assembleur ^^.
Dit moi, comment as tu appris l'assembleur??


Fedora Cambridge i386
Zenwalk 5.2
-------------
Il y a 10 types de personnes : celles qui connaissent le binaire, et celles qui ne le connaissent pas.

Hors ligne

#13 Le 24/04/2008, à 08:03

dzouille

Re : erreur en assembleur

Je suis étudiante en informatique. J'ai commencer à l'apprendre l'an passée...

Hors ligne

#14 Le 24/04/2008, à 08:23

Ultandir

Re : erreur en assembleur

Je suis étudiant en informatique aussi!
Tu est étudiante en quel année et ou?


Fedora Cambridge i386
Zenwalk 5.2
-------------
Il y a 10 types de personnes : celles qui connaissent le binaire, et celles qui ne le connaissent pas.

Hors ligne

#15 Le 24/04/2008, à 08:56

Nasman

Re : erreur en assembleur

Je débute l'assembleur sous Linux mais j'ai une bonne expérience sous Windows. Il y a une chose qui m'horripile c'est l'instruction mul byte[deux] qui peut être avantageusement remplacé par des shl eax,1.
De même pour multiplier par dix on peut utiliser l'instruction
lea edx,[eax+4*eax] qui "multiplie par 5" suivi d'un shl edx,1
Pour diviser par dix on multiplie par 1/10 à une puissance de deux près.

Plus quelques petites optimisations de code:
pour mettre à zéro remplacer mov eax,0 par xor eax,eax
pour tester si zéro remplacer cmp eax,0 par and eax,eax

Par compte je profite de ce post pour apprendre comment gérer le clavier et la création de fichiers sous Linux.
J'attend la sortie de Hardy 64 pour tester l'assembleur en 64 bits.


PC fixe sous Bionic 64 bits et portable avec Focal 64 bits

Hors ligne

#16 Le 24/04/2008, à 09:45

tafari

Re : erreur en assembleur

mon dieu je pensais pas que des gens pouvais faire de l'assembleur durant leur temps libre... c'était ma hantise en cours d'info...:(

Hors ligne

#17 Le 24/04/2008, à 09:59

dzouille

Re : erreur en assembleur

Ultandir, je suis étudiante en 1er, j'ai recommencer... j'étudie à bruxelles (la heb - esi)
tafari, si je fais autant d'assembleur c'est parce que je n'aimais pas du tout l'an passée, mais je compte bien reussir cette année, et pas me contenter de reussir tout juste wink moi aussi c'est le cours que j'aime le moins, mais je dois y passer...
Nasman, oui j'ai changer le mul byte[deux] par un shl eax,1... c'est beaucoup mieux  smile

Hors ligne

#18 Le 24/04/2008, à 10:07

Ultandir

Re : erreur en assembleur

Assembleur, SHELL, C et C++ sont mes langages de prédilection ^^ ( oui je sais je suis fou )

EDIT : Dzouille peut tu me faire parvenir tes cours? Ca m'interesserait d'en avoir plus ( parce que nous nous avons fait très peu d'assembleur et seulement en première année)

Dernière modification par Ultandir (Le 24/04/2008, à 10:09)


Fedora Cambridge i386
Zenwalk 5.2
-------------
Il y a 10 types de personnes : celles qui connaissent le binaire, et celles qui ne le connaissent pas.

Hors ligne

#19 Le 24/04/2008, à 10:50

dzouille

Re : erreur en assembleur

Je ferais ça ce soir sans faut, la je suis à l'ecole, et j'ai pas mes cours sous la main.

Hors ligne

#20 Le 24/04/2008, à 10:54

Ultandir

Re : erreur en assembleur

OK, Merci beaucoup d'avance!!
Tu pourra me les envoyer par mail? ( normalement, tu devrait pouvoir m'envoyer un mail si tu va dans la description de mon profil puis envoyer un mail )


Fedora Cambridge i386
Zenwalk 5.2
-------------
Il y a 10 types de personnes : celles qui connaissent le binaire, et celles qui ne le connaissent pas.

Hors ligne

#21 Le 24/04/2008, à 20:19

Le Farfadet Spatial

Re : erreur en assembleur

Salut à tous !

Nasman a écrit :

Il y a une chose qui m'horripile c'est l'instruction mul byte[deux] qui peut être avantageusement remplacé par des shl eax,1.
De même pour multiplier par dix on peut utiliser l'instruction
lea edx,[eax+4*eax] qui "multiplie par 5" suivi d'un shl edx,1
Pour diviser par dix on multiplie par 1/10 à une puissance de deux près.

Plus quelques petites optimisations de code:
pour mettre à zéro remplacer mov eax,0 par xor eax,eax
pour tester si zéro remplacer cmp eax,0 par and eax,eax

Bien sûr, Nasman, tu as parfaitement raison. Cependant, de mon côté, il y a une chose qui me fascine : les conseils d'optimisation qui permettent de grappiller quelques cycles, mais qui oublient ce qui fait réellement gagner des performances au code.

   Ce qui fait vraiment gagner en performances et qui sont à peu près accessibles à l'être humain :

      -- faire attention à l'alignement dans les caches (ça c'est plutôt fait dans le code de Dzouille) ;

      -- éloigner autant que possible les instructions qui dépendent d'autres instructions les unes des autres afin d'utiliser au mieux les capacités de parallélisme du processeur (assez délicat dans l'exemple de Dzouille) ;

      -- dérouler les boucles (ce que Dzouille ne l'a pas du tout fait).

   Et ça, ça rapporte autrement plus que xor eax,eax à la place de mov ax,0.

   Après, il faut aussi savoir qu'un processeur 16 bits manipule mieux les données 16 bits, un processeur 32 bits manipule mieux les données de 32 bits et ainsi de suite (alignement dans le bus et tout ça). Cela ressemble à une lapalissade, mais cela signifie qu'on a souvent intérêt à utiliser les registres équivalents.

   Cela dit, Dzouille, autant la première version que tu as postée ne me plaisait pas trop, autant je trouve ta dernière version plutôt bien.

   À bientôt.

                                                                                                                     Le Farfadet Spatial

Edit : j'ai supprimé les preuves comme quoi j'ai appris l'assembleur sur des machines 16 bits...

Dernière modification par Le Farfadet Spatial (Le 24/04/2008, à 20:20)

Hors ligne