Arm
Discutez d'informatique ici !
-
Rockleader
- Habitué(e)
- Messages: 2126
- Enregistré le: 11 Oct 2011, 18:42
-
par Rockleader » 26 Sep 2014, 18:49
Salutation,
Je voudrais avoir votre avis sur cet exo de tp (on est censé faire ça sur éclipse, et franchement pour vérifier la compilation c'est du grand n'importe quoi è_é )
Enfin bref^^
La consigne c'est écrire un programme qui transforme les minuscules d'une chaine en majuscule.
La chaine je l'ai initialisé dans mon main pour tester, autrement ça se ferait pas sous programme j'imagine mais là c'est pas le but.
- Code: Tout sélectionner
.global _start @généré par éclipse je sais pas ce que ça veut dire
chaine: .asciz "Bonjour" @ chaine = "Bonjour"
.align 4_start: @on nous a fait rajouté ça en tp mais je sais pas pourquoi ...
bl reset @pareil je sais pas d'ou ça vient
@commençons donc le programme^^
ADR r0,chaine @ on charge dans r0 l'adresse de la chaine
TQ:
LDRB r1,[r0] @on charge dans r1 le caractère contenu dans la chaine à l'adresse r0
cmp r1,#0 @on compare avec 0 adresse de null si on est en fin de chaine
BEQ finTQ @ si égal traitement fini
cmp r1,#'a'
BLO TQ @si c'est pas une minuscule
cmp r1,#'z'
BHI TQ @si c'est pas une minuscule
SUB r1,r1,#32 @on transforme la minuscule en majuscule
STRB r0,[r1] @on charge cette majuscule à l'adresse de la minuscule de plus on met STRB pour byte car on est pas avec des entiers ?
ADD r0,r0,#1 @ on passe à l'adresse suivante
B TQ
finTQ: b exit
exit: b exit
Je voudrais déjà savoir si sur mes commentaires par rapport à ce que j'ai écris je suis pas trop à la ramasse.
Dans un second temps je voudrais bien savoir si mon programme est bon ou pas^^
PS: Je me rend compte que si je tombe sur un caractère qui n'est pas une minuscule je ne change pas l'adresse et j'ai donc une boucle infini à priori., je devrais faire un ADD de 1 à r0 avant chaque retour au tant que.
Mais à part ça ?
Cette histoire est entièrement vraie puisque je l'ai inventé du début à la fin !
-
ampholyte
- Membre Transcendant
- Messages: 3940
- Enregistré le: 21 Juil 2012, 07:03
-
par ampholyte » 29 Sep 2014, 08:32
Bonjour,
Pourquoi ne fais-tu pas quelques choses de plus simple :
En pseudo code :
- Code: Tout sélectionner
/* On boucle sur cela */
SI r1 >= 'a' :
SI r1 <= 'z' :
r1 += 32
FIN SI
FIN SI
/* On passe à l'adresse du prochain caractère */
Comme ça tu n'auras plus de problème lorsque ton caractère n'est pas une lettre.
Ps : je n'ai aucune connaissance en arm mais il me semble que tu te compliques un peu la vie au niveau de tes conditions.
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0204j/Cihiddid.html
-
Rockleader
- Habitué(e)
- Messages: 2126
- Enregistré le: 11 Oct 2011, 18:42
-
par Rockleader » 05 Oct 2014, 10:28
Pour l'exemple ci dessus tu avais raison, j'ai pu modifier ;)
Sinon je viens de coder atoi en arm.
Qui effectue le traitement suivant 5f4t9 va retourner 549.
Je dois maintenant implémenter itoa qui à partir de 549 doit retourner "549"
L'astuce ce sera de récupérer chaque chiffre un par un pour les stocker après j'imagine, mais j'arrive pas à me représenter l'algo
Au début je pensais à un truc assez basique, une division par 10 et on récupère le reste à chaque fois. Mais je sais pas si on peut faire ça en arm ;)
Cette histoire est entièrement vraie puisque je l'ai inventé du début à la fin !
-
Rockleader
- Habitué(e)
- Messages: 2126
- Enregistré le: 11 Oct 2011, 18:42
-
par Rockleader » 05 Oct 2014, 12:50
Et pour te donner envie de faire de l'arm, atoi :d
- Code: Tout sélectionner
.global _start
_start: bl reset
ADR r1,chaine
stmfd r13!,{r1}
bl atoi
ADD r13,r13,#4
exit: b exit
atoi: stmfd r13!,{r1,r2,r3,r4,r5,r6,r14}
mov r2,#0
mov r0,#0
ldr r1,[r13,#28] @on récupère dans r1 l'adresse de la chaine
TQ: ldrb r3,[r1,r2]@on lit dans r0 le caractère à l'adresse r1+r2
cmp r3,#0
beq FIN
cmp r3,#48
blo FINTQ
cmp r3,#57
bhi FINTQ
@c'est un chiffre
mov r4,r3 @r4=valeur du caractere
mov r5,r0 @r5=chiffre stocké, 0 au début
mov r6,#10 @r6=10
mul r0,r5,r6 @r0=r5*10
add r0,r0,r4 @ r0=ancien chiffre*10 + nouveau
FINTQ: add r2,r2,#1
B TQ
FIN: ldmfd r13!,{r1,r2,r3,r4,r5,r6,r15}
chaine: .asciz "a34b_,2"
.align 4
Sinon j'ai pas vu l'instruction de division (ça revient à faire des décalages de bits vers la droite ou la gauche et ça à la limite je sais faire).
Le modulo non plus j'ai pas vu mais l'utiliser me simplifierait bien la vie :d
J'imagine que ça doit etre comme ça
MLS r0,#250,#10 @ r0 prend la valeur 0
EDIT
MLS{cond} Rd, Rn, Rm, Ra
The MLS instruction multiplies the values from Rn and Rm, subtracts the result from the value from Ra, and places the least significant 32 bits of the final result in Rd.
admettons que j'ai
r1 = 250
r2 = 10
je veux le résultat dans r0.
Je lappelle comment l'instruction ? J'ai un doute ^^
r0,r1,r2,???
Cette histoire est entièrement vraie puisque je l'ai inventé du début à la fin !
-
fatal_error
- Membre Légendaire
- Messages: 6610
- Enregistré le: 22 Nov 2007, 12:00
-
par fatal_error » 05 Oct 2014, 13:42
ben déjà, MLS prend 4 opérandes...donc ca risque pas detre r0,r1,r2.
ou alors ya des paramètres par défaut, mais jcrois pas trop...
bref, la def du modulo
a%b = r
signifie
a=bq+r, avec r < b
Tu remplaces a, par Ra, b par Rn, q par Rm, et r par Rd...
idem Rd prend la soustraction de bq à a.
pour 254 % 10, tu t'attends à trouver r=4.
MLS Rd, 10, Rm, 254
avec Rm qui vaut 254/10 = 25
et pour la division je comprends pas pourquoi tu dis que t'as pas vu, UDIV comme je l'ai cité existe...
UDIV Rd, 254, 10
la vie est une fête

-
Rockleader
- Habitué(e)
- Messages: 2126
- Enregistré le: 11 Oct 2011, 18:42
-
par Rockleader » 05 Oct 2014, 15:17
Je disais que je ne l'avais pas vu en cours.
Ou plutôt on l'a vu par l'intermmédiaire des shift
01 = 1
10 = 2
100=4
Donc en fait un LSL de 1 fait une multiplication par 2 et un LSR une division.
Ok pour le modulo ;)
Cette histoire est entièrement vraie puisque je l'ai inventé du début à la fin !
-
ampholyte
- Membre Transcendant
- Messages: 3940
- Enregistré le: 21 Juil 2012, 07:03
-
par ampholyte » 06 Oct 2014, 07:47
Rockleader a écrit:Je disais que je ne l'avais pas vu en cours.
Ou plutôt on l'a vu par l'intermmédiaire des shift
01 = 1
10 = 2
100=4
Donc en fait un LSL de 1 fait une multiplication par 2 et un LSR une division.
Ok pour le modulo

Oui mais cela fonctionne pour des puissances de 2 évidemment. D'ailleurs tu peux retrouver ça en C.
- Code: Tout sélectionner
a = b >> 2; /* Divise par 2² = 4*/
a = b << 2; /* Multiplie par 2² = 4 */
Comment tu gères pour une division par 3 par exemple ? La division est un peu plus compliquée qu'un simple déplacement de bit.
-
Rockleader
- Habitué(e)
- Messages: 2126
- Enregistré le: 11 Oct 2011, 18:42
-
par Rockleader » 07 Oct 2014, 17:02
Je suis allé voir ma prof ce matin pour lui demander; et elle m'a affirmé qu'il n'y avait pas de commande pour faire le modulo en arm, qu'on était obligé de le coder^^
Cette histoire est entièrement vraie puisque je l'ai inventé du début à la fin !
-
fatal_error
- Membre Légendaire
- Messages: 6610
- Enregistré le: 22 Nov 2007, 12:00
-
par fatal_error » 07 Oct 2014, 18:21
ben t'aurais du lui demander pour quel type d'architecture précisément et surtout demander quelles sont les instructions autorisées... parce que ca se fait il sait même pas que MLS ca marche ou pire, tu vas pondre un truc avec ton compilo qui est pas compatible avec celui que le prof utilise....
sinon, ben t'as qu'à implémenter toi même la fonction modulo...
la vie est une fête

-
Rockleader
- Habitué(e)
- Messages: 2126
- Enregistré le: 11 Oct 2011, 18:42
-
par Rockleader » 08 Oct 2014, 12:44
Ben du coup c'est ce que j'ai fais...
C'est un peu sale mais je l'ai fais passé par registre.
- Code: Tout sélectionner
modulo10: stmfd r13!,{r14} @modulo de r1 et 10
mov r0,r1
tq: cmp r0,#10
blo fin
sub r0,r0,#10
b tq
fin: ldmfd r13!,{r15} @en sortie r0 vaut r1 mod 10
Bon du coup, mon main pour itoa
- Code: Tout sélectionner
main : mov r2,#123 @l'entier qu'on voudra transformer en string
mov r3,#444 @l'adresse ou on stockera la chaine
stmfd r13 !, {r2}
stmfd r13 !, {r3} @ on empile l'entier et l'adresse de l'entier
bl itoa @on lance le sous programme
add r13,r13,#8 @on remet la pile dans sa position de départ
Et maintenant la fonction itoa avec laquelle je galère encore quand même.
- Code: Tout sélectionner
itoa: stmfd r13 ! {r1,r2,r3,r14}
ldr r1,[r13,#16] @ r1 = nombre
ldr r2,[r13,#12] @ r2 = adresse
mov r3,r1 @r3 est une copie de r1=nombre
TQ: cmp r1,10
blo FIN
@si le nombre est plus grand que 10
Bl modulo10 @ r0 = r1 mod 10
udiv r1,r1,10 @ r1 = r1/10
@Il me manque ici le travail principal de itoa; à savoir une fois qu'on a récupéré le modulo, il faut le stocker à l'adresse contenu dans r2. Et ainsi de suite pour chaque modulo à chaque tour d'itération.
Mais là par contre je sais pas du tout comment faire !
@ici on a donc dans r1 le nombre entier divisé par 10 et on peut reboucler
B TQ
FIN: ldmfd r13 ! {r1,r2,r3,r15} @rend la main au prog principal
Cette histoire est entièrement vraie puisque je l'ai inventé du début à la fin !
Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 1 invité