linuxux
Messages postés6Date d'inscriptionmardi 27 décembre 2005StatutMembreDernière intervention31 décembre 2005 29 déc. 2005 à 11:19
Salut,
Alors alors... J'ai mis sur papier ce que tu m'avais donné et j'ai vu qu'en fait ce bout de code ne faisait.... rien ! En fait, la dernière instruction compare ebx et edx. ebx 463960 vu que l'on n'y a pas touché depuis le début et edx 0 (c'est le reste restauré avec le pop). Donc, avec ce bout de code, jamais on aura ebx <= edx pourquoi faire le teste alors ? Elle est la l'erreur ? Donc on ne saute pas à L1 et on continue :
Le reste ...
movl $str,%ebx ; ebx str 0,0,0,0,0,0,0,0,0,0,0 (??) movl d,%eax ; eax d 1 movl $0,%edx ; edx = 0
movl $10,%ecx ; ecx = 10divl %ecx ; edx:eax / ecx ( edx reste 10, eax = quotient = 0) movl %eax,d ; ah qu'est-ce qu'on fait la, on met eax dans d ou d dans eax ? Le premier me parait impossible.
En tout cas merci pour ta réponse... on avance petit à petit.
linuxux
Messages postés6Date d'inscriptionmardi 27 décembre 2005StatutMembreDernière intervention31 décembre 2005 29 déc. 2005 à 14:16
Salut patatalo,
Alors ce serait un convertisseur ASCII. Mais qu'est-ce que l'on cherche à convertir ? Une donnée tapée au clavier ? Ou plutôt 463960 ? ou une autre variable ?
Pour le reste voyons voir :
movl %eax,d ; d eax 463960 (avant d valait 1) L2: movl d,%eax ; eax d 463960 (étrange on a fait l'inverse juste au dessus.)
movl $0,%edx ; edx = 0 movl $10,%ecx ; ecx = 10 divl %ecx ; edx:eax / ecx ( edx reste 0, eax = quotient = 46396) movl %eax,d ; d eax 46396 movl i,%eax ; eax i 463960
movl $0,%edx ; edx = 0 (il le valait déjà) movl d,%ecx ; ecx d 1 divl %ecx ; edx:eax / ecx ( edx reste 0, eax = quotient = 463960) movl %edx,i ; i edx 0 movl j,%ecx ; ecx j 0,0,0,0 (comprend pas la)
movl $0,%edx ; edx = 0 addl $'0',%eax ; on additionne le code ASCII de '0' avec eax, le résultat est dans eax : eax 463960 + 48 464008 movb %al,%ds:(%ebx,%ecx,1) ; alors la je coince
Ne sachant pas si ecx a été modifié je ne peux pas continuer pour l'instant.
cs_patatalo
Messages postés1466Date d'inscriptionvendredi 2 janvier 2004StatutModérateurDernière intervention14 février 20142 30 déc. 2005 à 09:12
re,
movb $0,%ds:(%edx,%eax,1) ; donne "mov byte ptr [edx+eax*1],0" ( mais alors là a verifier soit au desassembleur soit sur la doc de l'assembleur linux, je ne le connais pas assez ).Le segment ds n'est pas a preciser a moins d'utiliser ebp et esp en base d'acces memoire.
ce bout de code:
movl %eax,d
L2:
movl d,%eax
on met a jour la variable d mais eax peut necessiter une remise a jour lors de la boucle L2 donc cette suite d'instruction est tout a fait normal.
que cherche t'on dans la boucle L1:
cmpl %edx,%ebx
jbe L1 ; edx ebx quand d ecx = 1000000 ( le below est pour plus de sureté )
cette boucle ne cherche qu'a ajuster d
ensuite, d est redivisé par 10 juste avant L2 ( d = 100000 )
il ne te reste plus que L2 a traduire.
c'est L2 qui convertis decimal -> ascii dans le buffer str
la convertion en ascii s'opere par l'ajout du caractere '0' a la valeur eax.
on sauve ensuite dans [ebx+ecx*1] ( ebx = OFFSET str et ecx = j a ce moment là )
la suite ascii "0123456789" donne 30h,31h,32h,... ( "0" = 30h )
le zero terminal est ajouté au final.
movb $0,%ds:(%edx,%eax,1) ( ebx OFFSET str, eax j )
là par contre, je comprends pas:
movl $1,%eax ; eax = 1
movl $0,%eax ; eax = 0
int $0x80 ; syscall linux ? terminaison programme
linuxux
Messages postés6Date d'inscriptionmardi 27 décembre 2005StatutMembreDernière intervention31 décembre 2005 30 déc. 2005 à 11:33
re,
Bon je viens de me rendre compte que j'ai mal recopié l'exo, le jump vers L1 c jne et pas jbe. Vraiment désolé...
bon on récapépette.
.data
str: .zero 11
i: .long 463960
d: .long 1
j: .zero 4
.text .globl _start
_start: movl i,%ebx ; ebx = 463960
L1: movl i,%eax ; eax = 463960 movl $0,%edx ; edx 0 ($ dec) movl d,%ecx ; ecx d 1 divl %ecx ; edx:eax / ecx ( edx reste 0, eax = quotient = 463960) la on a rien changé
push %edx ; sauve le reste 0 dans la pile
movl $10,%eax ; eax = 10 mull %ecx ; eax * ecx 10 * 1, le resultat est dans eax, donc eax 10 on a rien changé
pop %edx ; on restore le reste edx = 0 movl %eax,d ; d eax 10 cmpl %edx,%ebx ; si ebx !edx alors on retourne a L1, et ebx 463960 et edx = 0 (cf le pop)
jne L1 ; donc on retourne a L1
mull %ecx ; eax * ecx 10 * 10, le resultat est dans eax, donc eax 100
pop %edx ; on restore le reste edx = 0
movl %eax,d ; d eax 100
cmpl %edx,%ebx ; si ebx !edx alors on retourne a L1, et ebx 463960 et edx = 0 (cf le pop)
jne L1 ; donc on retourne a L1
......
Donc en gros on effectue la boucle 7 fois, jusqu'à ce que d = 1000000 pour que, lors de la division, on ait le reste égale à 463960. Algorithmiquement, ce n'est pas très malin.
Pour L1, c'est ok !
La suite....
movl $str,%ebx ; on mets str dans ebx (c'est pour travailler avec ebx au lieu de travailler directement avec str ?) movl d,%eax ; eax d 1000000
movl $0,%edx ; edx = 0
movl $10,%ecx ; ecx = 10 divl %ecx ; edx:eax / ecx ( edx reste 0, eax = quotient = 100000)
movl %eax,d
linuxux
Messages postés6Date d'inscriptionmardi 27 décembre 2005StatutMembreDernière intervention31 décembre 2005 30 déc. 2005 à 11:38
oup désolé j'ai cliqué alors que j'avais pas fini !
je continue...
movl %eax,d ; on met à jour d = 100000
La voila l'erreur algorithmique ! Enfin je pense.... On sait que l'on a un zéro de trop pour d, donc on refait une division par 10. Cette erreur aurait pu être corrigé dans la boucle L1.
J'ai toujours une petit question : qu'est-ce que l'on cherche à convertir en ASCII ? quelle valeur ? là je vois pas.
Je vais bouquinner pour la ligne movb $0,%ds:(%edx,%eax,1)
cs_patatalo
Messages postés1466Date d'inscriptionvendredi 2 janvier 2004StatutModérateurDernière intervention14 février 20142 30 déc. 2005 à 14:18
re,
la valeure convertie est i ( laquelle veut tu que ce soit d'autre ??? )
c'est une methode qui permet de partir par la valeur la plus elevée vers la valeur la moins elevée, il doit effectivement etre plus judicieux de partir par la valeur la plus basse, de stocker dans un buffer temporaire et de reverser du buffer temporaire vers str. ( on evite la boucle L1 mais on s'oblige a avoir une valeur max de X caracteres qui definira la taille du buffer temporaire )