En utilisant yyparse () pour deux assembleur de passe?
-
23-08-2019 - |
Question
J'écris un assembleur pour un contrôleur de micro personnalisé je travaille. J'ai l'assembleur à un point où il se chargera du montage des instructions jusqu'à binaire.
Cependant, je suis maintenant des problèmes avec l'obtention des étiquettes de travailler. À l'heure actuelle, lorsque mon assembleur rencontre un nouveau label, il stocke le nom de l'étiquette et l'emplacement de la mémoire de sa référence. Lorsqu'une instruction fait référence à une étiquette, l'assembleur regarde l'étiquette et remplace l'étiquette avec la valeur appropriée.
Ceci est bien beau, mais si l'étiquette est définie après le référencement instruction il? À cause de cela, je dois avoir mon analyseur courir sur le code deux fois.
Voici ce que j'ai actuellement ma principale fonction:
303 int main(int argc, char* argv[])
304 {
305
306 if(argc < 1 || strcmp(argv[1],"-h")==0 || 0==strcmp(argv[1],"--help"))
307 {
308 //printf("%s\n", usage);
309 return 1;
310 }
311 // redirect stdin to the file pointer
312 int stdin = dup(0);
313 close(0);
314
315 // pass 1 on the file
316 int fp = open(argv[1], O_RDONLY, "r");
317 dup2(fp, 0);
318
319 yyparse();
320
321 lseek(fp, SEEK_SET, 0);
322
323 // pass 2 on the file
324 if(secondPassNeeded)
325 {
326 fp = open(argv[1], O_RDONLY, "r");
327 dup2(fp, 0);
328 yyparse();
329 }
330 close(fp);
331
332 // restore stdin
333 dup2(0, stdin);
334
335 for(int i = 0; i < labels.size(); i++)
336 {
337 printf("Label: %s, Loc: %d\n", labels[i].name.c_str(), labels[i].memoryLoc);
338 }
339 return 0;
340 }
J'utilise cette configuration dans un flex / bison.
La solution
Si c'est tout ce dont vous avez besoin, vous n'avez pas besoin deux passes assembleur complet. Si l'étiquette n'est pas définie lorsque vous faites référence, vous un remplaçant simplement l'adresse sortie (par exemple 0x0000) et ont une structure de données qui répertorie tous les lieux avec des références avant et quel symbole ils en annexe. A la fin du fichier (ou bloquer si vous avez des symboles locaux), vous allez simplement à travers cette liste et patcher les adresses.