октября 13, 2011

Условные переходы

Сессия сдана, пришло время продолжить разработки.

Как я уже писал раньше, я пишу транслятор ассемблера. Только что пройден исторический этап: транслятор начал поддерживать инструкции условных переходов. Ура!

Вот пример цикла:


: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 инструкции. Подробнее о том, как я делал этот транслятор и о том, как сделать свой транслятор, напоминаю, планируется большой цикл статей.


Комментариев нет:

Отправить комментарий

Постоянные читатели

Обо мне

Моя фотография
Мой e-mail: vitek_03(at)mail(dot)ru