Вы можете ознакомиться с некоторыми уже созданными ассемблерами, такими как PASMO: assmbler для Z80 CPU и получить от него идеи. Вот он: http://pasmo.speccy.org/
Я написал пару очень простых ассемблеров, причем оба они используют строковые манипуляции с помощью strtok() и тому подобное. Для простой грамматики, такой как язык ассемблера, достаточно. Ключами моих сборщиков являются:
Таблица символов: всего лишь массив структур, с именем символа и его значением.
typedef struct
{
char nombre[256];
u8 valor;
} TSymbol;
TSymbol tablasim[MAXTABLA];
int maxsim = 0;
Символ - это просто имя, связанное с этим значением. Это значение может быть текущей позицией (адресом, где будет собираться следующая инструкция), или может быть явным значением, назначенным псевдонимом EQU
.
Названия символов в этой реализации ограничены 255 символами, а один исходный файл ограничен MAXTABLA
символами.
я выполнить два прохода в исходный код:
Первый из них состоит в определении символов и хранить их в таблице символов, обнаруживать ли они с последующей EQU
инструкцией или нет. Если это так, значение, следующее к EQU
, анализируется и присваивается символу. В другом случае назначается значение текущей позиции. Чтобы обновить текущую позицию, мне нужно определить, есть ли действительная инструкция (хотя я еще не собираю ее) и обновить ее соответствующим образом (это легко для меня, потому что у моего процессора есть фиксированный размер инструкции).
Здесь у вас есть образец моего кода, который отвечает за обновление таблицы символов значением от EQU текущей позиции и, если необходимо, продвижение текущей позиции.
case 1:
if (es_equ (token))
{
token = strtok (NULL, "\n");
tablasim[maxsim].valor = parse_numero (token, &err);
if (err)
{
if (err==1)
fprintf (stderr, "Error de sintaxis en linea %d\n", nlinea);
else if (err==2)
fprintf (stderr, "Simbolo [%s] no encontrado en linea %d\n", token, nlinea);
estado = 2;
}
else
{
maxsim++;
token = NULL;
estado = 0;
}
}
else
{
tablasim[maxsim].valor = pcounter;
maxsim++;
if (es_instruccion (token))
pcounter++;
token = NULL;
estado = 0;
}
break;
Второй проход, где я на самом деле собрать инструкции, заменяя символ с его значением, когда я нашел. Это довольно просто, используя strtok()
разделить линию на ее компоненты, а также с помощью strncasecmp()
сравнить то, что я нахожу с мнемоникой
Нормальный, что-то вроде этого будет выполняться с помощью 'yacc' и' lex'. – Devolus
Вы забыли указать свой код .... – laaposto
'yacc'and' lex' выглядит довольно круто, к сожалению, мне не разрешено использовать их :( – Nax