Utilizzando yyparse () per fare un assemblatore a due passaggi?
-
23-08-2019 - |
Domanda
Sto scrivendo un assemblatore per un controllore micro personalizzato su cui sto lavorando. Ho l'assemblatore ad un punto in cui assemblerà le istruzioni fino al binario.
Tuttavia, ora sto avendo problemi con ottenere etichette di lavorare. Attualmente, quando il mio assemblatore incontra una nuova etichetta, memorizza il nome del marchio e la posizione di memoria il suo riferimento a. Quando si fa riferimento a un'istruzione un'etichetta, l'assemblatore guarda l'etichetta e sostituisce l'etichetta con il valore appropriato.
Questo è bene e dandy, ma cosa succede se l'etichetta è definita dopo l'istruzione fa riferimento a esso? A causa di questo, ho bisogno di avere il mio parser investito il codice due volte.
Ecco quello che ho attualmente per la mia funzione principale:
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 }
Sto usando questo all'interno di una configurazione di flex / bisonti.
Soluzione
Se questo è tutto ciò che serve, non hai bisogno di un full assemblatore a due passaggi. Se l'etichetta non è definita quando si fa riferimento, è semplicemente uscita uno stand-in indirizzo (ad esempio 0x0000) e hanno una struttura dati che elenca tutti i luoghi con i riferimenti in avanti e quale simbolo si riferiscono alla. Alla fine del file (o il blocco se si dispone di simboli locali), è sufficiente passare attraverso quella lista e patch gli indirizzi.