Posté le 15/03/2022 20:03
Planète Casio v4.3 © créé par Neuronix et Muelsaco 2004 - 2024 | Il y a 66 connectés | Nous contacter | Qui sommes-nous ? | Licences et remerciements
Planète Casio est un site communautaire non affilié à Casio. Toute reproduction de Planète Casio, même partielle, est interdite.
Les programmes et autres publications présentes sur Planète Casio restent la propriété de leurs auteurs et peuvent être soumis à des licences ou copyrights.
CASIO est une marque déposée par CASIO Computer Co., Ltd
Citer : Posté le 15/03/2022 20:06 | #
C'est du SuperH. Tutoriel d'initiation ici : https://www.planet-casio.com/Fr/forums/topic12345-1-tutoriel-initiation-a-lassembleur-superh.html
Et des infos un peu plus à jour côté gint par ici : https://www.planet-casio.com/Fr/forums/topic16807-2-casm-optimiser-au-cycle-pres-la-reference.html#184936
Exécuter de l'assembleur c'est facile il suffit d'y sauter en C. Le plus dur c'est de l'assembler, parce que même si les instructions elles-mêmes ont une traduction directe en hexa, dès que tu as des labels, des références à d'autres variables ou fonctions du code, etc. il faut linker et ça c'est plus difficile.
Citer : Posté le 15/03/2022 20:48 | #
Coucou !
Merci pour tes liens, je vais regarder ça attentivement.
Pour la dernière partie on s’est mal compris :
En gros je voudrais que l’utilisateur puisse rentrer du code assembleur, que ce dernier soit assemblé et ensuite exécuté, donc il n’est pas directement dans le code du programme…
Citer : Posté le 15/03/2022 20:50 | #
Oui, c'est bien ça qui est difficile : linker le code assembleur entré par l'utilisateur
Citer : Posté le 15/03/2022 21:25 | #
Heu, le linkage c'est pas l'opération qui permet de rassembler tous les fichiers différents et les labels ?
Pour moi le problème ce serait plus à l’exécution : on ne peut pas faire un saut en C vers le code puisqu'il n'existe pas à la compilation de l'add-in (le code est créé dans l'add-in)...
Citer : Posté le 15/03/2022 21:39 | #
Oui, si tu regardes le processus de développement sur le PC, l'édition des liens c'est l'étape qui consiste à rassembler tous les fichiers et à résoudre les références.
Si ton code assembleur ne fait absolument rien à part du calcul et n'appelle aucune fonction externe, tu n'as pas de liens à éditer. Mais si ton code assembleur doit interagir avec n'importe quoi d'autre dans le programme, genre appeler dpixel() ou cos() ou aller lire la valeur d'une variable globale, tu vas te retrouver assez vite coincé parce que tu ne pourras pas éditer les liens. (Il faudrait insérer l'adresse de la fonction ou variable concernée, mais le problème c'est qu'une fois à l'exécution les noms des variables/fonctions sont perdus !) Tu seras obligé de «tricher» de différentes façons.
Il y a un processus similaire à faire dans tous les cas, qui est la résolution des labels dans ton code assembleur. Personne n'a envie d'écrire ça :
mov.l @(4,pc),r0
mov.l @(8,pc), r1
rts
add r1, r0
.long 0xc0ffee
.long 0x8c000000
Non seulement parce que c'est moche mais surtout parce qu'il faut recalculer le 4 et le 8 chaque fois qu'on change la distance entre le mov.l et le .long correspondant.
À la place, on veut écrire ça :
mov.l .x,r0
mov.l .y, r1
rts
add r1, r0
.x: .long 0xc0ffee
.y: .long 0x8c000000
Et donc ton assembleur il doit résoudre les labels pour générer l'hexadécimal correspondant à @(4,pc) et @(8,pc), ce qui est la version facile (quoique pas gratuite non plus) de l'édition des liens. J'ai un peu mis les deux dans le même panier dans ma réponse précédente.
Quant à ce qui est de sauter vers le code, tu n'as pas besoin qu'il soit dans l'add-in. Il suffit de le charger dans la RAM (s'il est position-independent, c'est encore tout un truc).
void assemble_code(...)
{
// On prétend que tu assembles du code, là je copie juste la fonction ci-dessus
uint32_t my_hardcoded_function[] = {
0xd001d102, 0x000b301c, 0x00c0ffee, 0x8c000000,
};
memcpy(asm_buffer, my_hardcoded_function, 16);
}
void call_code(...)
{
int (*code)(void) = (void *)&asm_buffer;
// Et pouf, la RAM est exécutable
(*code)();
}
Citer : Posté le 16/03/2022 12:51 | #
Ah, c’est plus clair comme ça, merci !
Du coup si je comprends bien @(4,pc) correspond à l’adresse 0xc0ffee ?
Je crois que j’ai quelques idées pour le linkage, en tout cas j’imaginais pas que le saut vers le code serait aussi simple, merci !
Citer : Posté le 16/03/2022 13:22 | #
Pour être exact @(4,pc) représente la position 4 octets après la position actuelle (plus des broutilles d'alignement/etc), ce qui est donc l'adresse de la valeur 0xc0ffee.
Citer : Posté le 16/03/2022 13:31 | #
Ah d’accord !
Mais pourquoi mettre @(8,pc) alors que le .long 0x8c[…] est à 5 octets de la position actuelle ?
Je sais qu’un long fait 4 octets, mais en memoire non, pas dans le code ?
Citer : Posté le 16/03/2022 13:43 | #
Chaque instruction fait 2 octets, chaque long fait 4 octets. La "taille d'un long dans le code" n'a pas de sens/d'intérêt, lorsque tu exécutes le programme le code source n'existe plus depuis très longtemps.
La distance entre le mov.l @(8,pc), r1 et le .long 0x8c000000 est donc de 10 octets, sauf que c'est pas si simple. Tu ne peux faire un accès mémoire de 4 octets que sur une adresse alignée à 4 octets (= multiple de 4), alors qu'une instruction peut être alignée à 2 octets. La formule exacte pour le calcul de la destination c'est donc (adresse_du_move & ~3) + 4 + valeur_deplacement, ce qui revient bien à PC+disp.
Ici le mov.l @(8,pc), r1 est à l'adresse 2, le déplacement est 8, ça donne bien l'offset 12.
Citer : Posté le 16/03/2022 17:11 | #
Ah,ok merci !