37Fermer39
BrunniLe 21/04/2009 à 21:28
J'ai avancé dans mon assembleur. C'est une grosse escroquerie ce truc, franchement si ça marche on peut me décerner la palme du bourrin happy
En fait le truc c'est que mon jeu d'instructions est tellement minimal qu'il n'est vraiment pas orthogonal. Prenons une instruction CPU bien pourrie: le branchement conditionnel (B[xx] ra, rb, saut_relatif_si_succès avec xx code de condition). Déjà il y a pour 14 bits d'opérande (sur 16), donc seulement 3 pour l'offset de branchement, c'est-à-dire [-4 .. +3].
Maintenant j'écris ceci:
:a
	BRA :b
	MOV r0, 0
	BNE r0, 0, :a
:b
	NOP

Le machin va me générer cela (il va mettre le 0 dans un registre, at, car BNE s'attend à ça seulement):
0000  BRA 3		; @0008
0002  MOV r0, 0
0004  MOV at, 0
0006  BNE r0, at, -4	; @0000
0008  NOP

Mais remplaçons bêtement le MOV r0, 0 par MOV r0, -1, qui ne peut plus être fait en une instruction:
0000  BRA 5		; @000c
0002  MOV r0, 255 (-1)
0004  EXT r0
0006  MOV at, 0
0008  BEQ r0, at, 1	; @000a
000a  BRA -6		; @0000
000c  NOP

(pendant l'exécution d'une instruction, pc vaut 'adresse de l'instruction exécutée' + 2. BRA -6 équivaut à SUB pc, 12)
Cette fois le le BNE est remplacé par un BEQ (inverse) qui skippe un branchement standard pour revenir plus haut. En fait tout le code a bougé, puisque l'instruction devenant plus grande car le label n'était pas assez proche, tout le reste du code est décalé, et et d'autres sauts peuvent éventuellement devenir à leur tour trop gros et nécessiter des instructions supplémentaires.
Bref -> grosse boucle while (des trucs ont bougé) { génère du code en fonction des labels actuels et ajuste la position des labels en fonction du nouveau code } comme un méga bourrin, et si un jour ça bloque on remplacera par un for grin