Сессия сдана, пришло время продолжить разработки.
Как я уже писал раньше, я пишу транслятор ассемблера. Только что пройден исторический этап: транслятор начал поддерживать инструкции условных переходов. Ура!
Вот пример цикла:
:asm-noname PREFIX *auto-integers? on mov eax 555 mov ebx 111 @> LOOP sub eax 2 sub ebx 1 jnz @@ LOOP mov d[ *out disp ] eax ret all-resolve \PREFIX asm-noname; execute |
Технические детали: при помощи :asm-noname ... asm-noname; execute код на асме транслируется и сразу запускается. Блок PREFIX ... \PREFIX указывает на то, что мы будем использовать префиксную запись инструкций (т.е. инструкции перед операндами). Вызов *auto-integers? on делает так, что целые числа автоматически считаются операндами команд. (Без этой опции после чисел 555, 111, 2, 1 нужно бы было просто вызывать команду imm. Это полезный режим, если мы хотим операнды вычислять, например, в этом режиме можно писать mov eax 64 1024 * imm, если не хочется в уме перемножать 64 и 1024. Кроме того, код может зависеть от чего-нибудь внешнего: например, тут mov eax timer imm заносится состояние таймера в момент трансляции, операнд в явном виде не указан.)
Теперь по коду. Сперва в соответствующие регистры кладётся 555 и 111. Далее, создаётся метка с именем LOOP. После этого в цикле из eax вычитается 2, из ebx вычитается 1 до тех пор, пока ebx не обнулится. То, что останется от eax, переносится в *out — глобальную переменную DEmbro, которую нужно определить выше, например, так:
variable *out
Но так делать вовсе необязательно, вместо *out может быть любой указатель. Как нетрудно догадаться, в *out будет занесено 333, далее с переменной можно работать из кода на DEmbro, или из следующей ассемблерной вставки. Таким образом ассемблер может обмениваться данными с DEmbro. Планируется более детальный механизм взаимодействия: из ассемблера можно будет получать доступ к стекам и другим структурам DEmbro-машины.
Команда all-resolve разрешает все метки. Дело в том, что на метку могут быть ссылки выше метки, ниже метки, или одновременно и так, и так. Нет возможности сразу это предугадать, поэтому метки и ссылки собираются в две таблицы, а в конце кода командой all-resolve ссылкам ставятся в соответствие метки и нужные адреса проставляются. Из-за этой муторности условные переходы и были написаны самыми последними среди прочих инструкций. Теперь, я надеюсь, мне осталось только перебить таблицы из документации к ia-32 в свой транслятор.
Сейчас транслятор поддерживает уже 84 инструкции. Подробнее о том, как я делал этот транслятор и о том, как сделать свой транслятор, напоминаю, планируется большой цикл статей.
Комментариев нет:
Отправить комментарий