Voir la version complète : [GBA][Aide] Questions sur l'assembleur sur GBA
Hello world,
je viens de me mettre à l'assembleur sur GBA (en attendant que le dev DS soit moins le bordel ... :p ), et je voudrais savoir un truc :
Y-a t'il une façon plus rapide que ldr r1, =0x10101010 de stocker 0x10101010 dans r1 ? En gros, peut-on stocker une valeur "inshiftable" dans un registre autrement qu'avec ldr, qui est plus lent que mov ?
je viens de me mettre à l'assembleur sur GBA (en attendant que le dev DS soit moins le bordel ... :p )
Rhoo :lol:
Y-a t'il une façon plus rapide que ldr r1, =0x10101010 de stocker 0x10101010 dans r1 ? En gros, peut-on stocker une valeur "inshiftable" dans un registre autrement qu'avec ldr, qui est plus lent que mov ?
Non, si elle n'est pas shiftable c'est impossible sauf erreur. Dans certains cas, lorsque le nombre n'est pas trop complexe, tu as intérêt à faire comme ça (exemple pour 0x123456):
mov r1, #0x120000
orr r1, r1, #0x3400
orr r1, r1, #0x56
Après 2 ou 3 instructions je pense que ça n'a plus aucun intérêt ni en terme de place ni performance, mais je ne saurais pas te dire exactement :)
Rhoo :lol:
:p T'es pas d'accord ? ^^
Non, si elle n'est pas shiftable c'est impossible sauf erreur. Dans certains cas, lorsque le nombre n'est pas trop complexe, tu as intérêt à faire comme ça (exemple pour 0x123456):
mov r1, #0x120000
orr r1, r1, #0x3400
orr r1, r1, #0x56
Après 2 ou 3 instructions je pense que ça n'a plus aucun intérêt ni en terme de place ni performance, mais je ne saurais pas te dire exactement :)
OK merci ; par curiosité, quel assembleur utilises-tu ?
EDIT:
comment fait-on pour appeler une "fonction" ? :S J'ai essayé plein de trucs, mais ça marche pas. help please ! ^^
Hello world,
je viens de me mettre à l'assembleur sur GBA (en attendant que le dev DS soit moins le bordel ... :p ), et je voudrais savoir un truc :
Y-a t'il une façon plus rapide que ldr r1, =0x10101010 de stocker 0x10101010 dans r1 ? En gros, peut-on stocker une valeur "inshiftable" dans un registre autrement qu'avec ldr, qui est plus lent que mov ?
ben , pour cette valeur en particulier, le plus rapide, c'est:
mov r1,0x1010
orr r1,r1,r1,lsl #16
Mikegba toujours là pour l'asm !
ben , pour cette valeur en particulier, le plus rapide, c'est:
mov r1,0x1010
orr r1,r1,r1,lsl #16
oups... je suis toujours là, .... mais pour raconter de grosses betises !:-'
en fait, c'est :
mov r1,0x10
orr r1,r1, lsl #8
orr r1,r1, lsl #16
ce coup là c'est bon.
Merci !
^^ Sinon c'est bon j'ai trouvé pour l'appel de fonctions ... ("bl nomfonction" pour ceux que ça interresserait v_v )
J'ai fait une petite fonction de plottage de pixels (par 4) en mode 4 :ph34r: . Pouvez-vous me dire si elle tient la route ou bien si elle est vraiment à ##### :berk: .
plot4:
mov r0, #0x06000000
orr r1, r1, r2, lsl #8
orr r1, r1, r3, lsl #16
mov r4, r4, lsl #16
orr r1, r1, r4, lsl #8
str r1, [r0]
bx lr
Sachant que les params sont :
r1: couleur pixel 1,
r2: couleur pixel 2,
etc jusqu'au pixel 4.
Je sens que Mikegba va dire qu'il peut l'optimiser à 600% :p
Excuse pour le double-post, mais j'ai besoin d'une info :
:S Comment fait-on pour effectuer une division (d'entiers) en assembleur ? :-* J'ai beau chercher, je ne vois pas d'instruction dans la doc ARM qui permette ça ... On n'est quand même pas obligé de réécrire une fonction de division quand même :blink: ?
Excuse pour le double-post, mais j'ai besoin d'une info :
:S Comment fait-on pour effectuer une division (d'entiers) en assembleur ? :-* J'ai beau chercher, je ne vois pas d'instruction dans la doc ARM qui permette ça ... On n'est quand même pas obligé de réécrire une fonction de division quand même :blink: ?
:D ben .....si , y'a pas de fonction de division ! faut en réécrire une soi meme...
edit: j'avais pas vu pour le plottage:
plot4:
mov r0, #0x06000000
orr r1, r1, r2, lsl #8
orr r1, r1, r3, lsl #16
orr r1, r1, r4, lsl #24 ( pas obligé de faire un mov r4,r4, lsl 16 avant )
str r1, [r0]
bx lr
mais ce genre de fonction marche uniquement quand tu es aligné en mémoire, ça marche plus pour une adresse comme 0#0x06000001 ou 0x06000002.
avec du décalage de bit c'est pas trop compliqué quand même... c'est un classique...
edit: j'avais pas vu pour le plottage:
plot4:
mov r0, #0x06000000
orr r1, r1, r2, lsl #8
orr r1, r1, r3, lsl #16
orr r1, r1, r4, lsl #24 ( pas obligé de faire un mov r4,r4, lsl 16 avant )
str r1, [r0]
bx lr
mais ce genre de fonction marche uniquement quand tu es aligné en mémoire, ça marche plus pour une adresse comme 0#0x06000001 ou 0x06000002.
Ce que tu veux dire, c'est que ça ne marche que sur les adresses : 0x06000000, 0x06000004, 0x06000008, etc, c'est ça ? Et sinon, par curiosité, sur ton tuto assembleur, tu avais parlé de plotter 40 pixels, ou un truc comme ça ; tu fais comment ?:blink:
D'ailleurs, à quand la 2ème partie de ce tuto ? Il était drôlement bien foutu, je viens de le découvrir.
:D ben .....si , y'a pas de fonction de division ! faut en réécrire une soi meme...
avec du décalage de bit c'est pas trop compliqué quand même... c'est un classique...
Ok, bon bah merci à tous ls deux :D C'est con de pas en avoir une pré-faite quand même :D Bon, bah je vais m'y mettre alors ^^
Ce que tu veux dire, c'est que ça ne marche que sur les adresses : 0x06000000, 0x06000004, 0x06000008, etc, c'est ça ? Et sinon, par curiosité, sur ton tuto assembleur, tu avais parlé de plotter 40 pixels, ou un truc comme ça ; tu fais comment ?:blink:
D'ailleurs, à quand la 2ème partie de ce tuto ? Il était drôlement bien foutu, je viens de le découvrir.
Ok, bon bah merci à tous ls deux :D C'est con de pas en avoir une pré-faite quand même :D Bon, bah je vais m'y mettre alors ^^
oui, ça ne marche que pour les adresses multiples de 4.
Pour les divisions, voir pour les multiplications, comme le dit DJP, ben oui, utilise les décalages de bits quand c'est possible.
Pour les multiplications, y'a pas mal d'astuces possibles, et tu peux combiner des décalages pour faire des multiplication qui sont pas par des puissances de 2
Par exemple, si tu veux multiplier par 240 ( ... vu qu'on est dans le mode 4:lol: ), genre pour avoir ton adresse en fonction de ta coordonée y :
on suppose au'on a déja dans r1 la coordonée y, donc comprise entre 0 et 240 et dans r2 la coordonée x:
mov r0,#0x6000000
add r0,r0,r1, lsl #8 ( on multiplie y par 256 et on l'ajoute à l'adresse du buffer)
sub r0,r0,r1, lsl #4 ( on multiplie y par 16 et on le soustrait de notre buffer , ce qui nous fait bien au final une multiplication par 240)
add r0,r0,r2 enfin, on ajoute notre coordonnée x.
r0 contient maintenant l'adresse ou on veut plotter.
la meme chose avec l'instruction mla ( multiplie et additionne ), mais plus couteuse en temps cpu
mov r0,#0x6000000
mov r3,#240
mla r4,r1,r3,r0 ( multiplie r1 par r3 et ajoute r0, met le résultat dans r4 )
add r0,r4,r2
on ne peut pas multiplier par une constante , obligé d'initialiser un registre avant ( ici r3 )
Sinon, pour la suite du tuto, ben à ce moment je combine un tuto assembleur et mode 4 , avec un exemple concret d'affichage d'une map de 2048*2048 avec des tiles software de 32*32, avec gestion soft du fliping horizontal et vertical des tiles.
Comme j'ai déja tout ça en stock , ça me prendrait pas trop de temps, et rien que ça ça permet de voir une tonne de truc : table de saut en asm, plot par 32 pixels en mode 4, manipulation de registre, etc....
oui, ça ne marche que pour les adresses multiples de 4.
Ok donc ça j'ai pigé :D
Pour les divisions, voir pour les multiplications, comme le dit DJP, ben oui, utilise les décalages de bits quand c'est possible.
Pour les multiplications, y'a pas mal d'astuces possibles, et tu peux combiner des décalages pour faire des multiplication qui sont pas par des puissances de 2
Par exemple, si tu veux multiplier par 240 ( ... vu qu'on est dans le mode 4:lol: ), genre pour avoir ton adresse en fonction de ta coordonée y :
on suppose au'on a déja dans r1 la coordonée y, donc comprise entre 0 et 240 et dans r2 la coordonée x:
mov r0,#0x6000000
add r0,r0,r1, lsl #8 ( on multiplie y par 256 et on l'ajoute à l'adresse du buffer)
sub r0,r0,r1, lsl #4 ( on multiplie y par 16 et on le soustrait de notre buffer , ce qui nous fait bien au final une multiplication par 240)
add r0,r0,r2 enfin, on ajoute notre coordonnée x.
r0 contient maintenant l'adresse ou on veut plotter.
la meme chose avec l'instruction mla ( multiplie et additionne ), mais plus couteuse en temps cpu
mov r0,#0x6000000
mov r3,#240
mla r4,r1,r3,r0 ( multiplie r1 par r3 et ajoute r0, met le résultat dans r4 )
add r0,r4,r2
on ne peut pas multiplier par une constante , obligé d'initialiser un registre avant ( ici r3 )
Merci pour le truc : j'y avais pas pensé ! >_<
Sinon, pour la suite du tuto, ben à ce moment je combine un tuto assembleur et mode 4 , avec un exemple concret d'affichage d'une map de 2048*2048 avec des tiles software de 32*32, avec gestion soft du fliping horizontal et vertical des tiles.
Comme j'ai déja tout ça en stock , ça me prendrait pas trop de temps, et rien que ça ça permet de voir une tonne de truc : table de saut en asm, plot par 32 pixels en mode 4, manipulation de registre, etc....
Génial, parce que la 1ère partie était bien précise, et que apprendre l'asm ARM avec juste la doc, c'est un peu lourd quand même :lol:
D'ailleurs, comment met-on le code en iwram avec GAS ? J'ai essayé
.section ".iwram"
mais mon code ne s'exécute plus :blink: Où est la bourde ?
Heu c'est .section .iwram.
Et sinon il faut que tu mettes des fonctions spécifiques de ton code en IWRAM, mais pas le main, qui commence toujours à une adresse spécifique (en ROM) il me semble ^^
Heu c'est .section .iwram.
Et sinon il faut que tu mettes des fonctions spécifiques de ton code en IWRAM, mais pas le main, qui commence toujours à une adresse spécifique (en ROM) il me semble ^^
Ok ; et ces portions de code, je dois faire des branchement dessus pour y accéder je présume ?
Bon sinon, je suis en train de coder une fonction de division qui doit arrondir SYSTEMATIQUEMENT au supérieur ; est-ce que le code qui suit (en ASM bien sur mais je n'ai pas eu le temps ... :whst: donc pour le moment en C ... ) placé à la fin de ma division euclidienne aura le résultat escompté ? :
if (reste > (diviseur >> 2)) resultat ++;
EDIT:
en gros, ça doit donner ça en ASM :
mov r2, r2, lsr #1
cmp r1, r2
addgt r0, r0, #1
où
r0 est le resultat
r1 est le reste
r2 est le diviseur
Heu ce serait pas plutôt if (reste > 0) resultat++ ?
Sinon, bien sûr que oui pour le branchement, vu que ce sont des fonctions ;)
Heu ce serait pas plutôt if (reste > 0) resultat++ ?
Sinon, bien sûr que oui pour le branchement, vu que ce sont des fonctions ;)
Oula ! Si je commence à avoir du mal en C à 19h >_< , je sais pas ce que ça va donner en ASM pendant la soirée :S ; donc corrigez-moi si je me trompe :ph34r: :
mov r2, r2, lsr #1
cmp r1, #0
addgt r0, r0, #1
où
r0 est toujours le resultat
r1 est toujours le reste
r2 est toujours le diviseur
EDIT:
Bon en fait j'ai un nouveau problème : j'aurais besoin de faire ceci :
r1 + (r2 / r3) * r4
jusque là pas trop de pb, mais il faudrait que j'arrondisse, comme pour la division, systématiquement au supérieur >_< ; quelqu'un aurait une idée ?
Parce que je ne pense pas qu'une conversion en nombre flottant + 0.5 le tout reconverti en entier, ça soit, très rapide ... >_< :D
vBulletin® v.3.7.2, Copyright ©2000-2008, Jelsoft Enterprises Ltd. Tous droits réservés - Version française vbulletin-fr.org