Лектор легко выделил глубоко усвоенную и хорошо переваренную
мысль, отчего вокруг распространился дух творчества.

+--------------------------------------------------------------------------------------------------------------------------[release: 07.11.04]----+
|
|
|
|
|
|
|
  _|_|    _|_|_|    _|_|    _|_|_|    _|_|    _|  _|    _|  _|_|    _|_|_|      _|  _|    _|_|_|
_|      _|  _|  _|  _|  _|  _|        _|  _|      _|_|_|_|  _|  _|  _|        _|_|_|_|_|  _|    
_|      _|_|_|_|_|  _|  _|  _|_|      _|_|    _|  _| |  _|  _|_|    _|_|_|      _|  _|    _|_|_|
_|      _|  _|  _|  _|  _|  _|        _|      _|  _|    _|  _|          _|    _|_|_|_|_|      _|
  _|_|    _|_|_|    _|_|    _|_|_|    _|      _|  _|    _|  _|      _|_|_|      _|  _|    _|_|_|
|
|
|
|
|
|
|
+-------------------------------------------------------------------------------------------------------------------------------------------------------+
+---------------------------------------------------[0x04: Мысли от SpellMasters 0x00]---------------------------------------------------+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

Данный текст - часть разработок группы SpellMasters.Мы надеемся,что кажущаяся абстрактность этой статьи не отпугнет читателя, и полученные результаты помогут кому-нибудь в его экспериментах с написанием компилятора (интерпретатора, транслятора), разработке и создании виртуальных машин. Мы НЕ БУДЕМ рассказывать о том, КАК написать все это, но мы покажем возможные подводные камни и варианты решений возникающих проблем. Нами планируется написать несколько подобных статей, все отклики мы ждем как на ящик журнала ([email protected]), так и на наши адреса (указаны в конце статьи).

SpellMasters.

Представим что у нас есть следующий код:
var a,b:integer;  //integer- 4 байта
    c,d:double;   //double - 8 байт
begin
    a=1;
    b=3;
    c=a-b;
    d=b-d;
end.
Рассмотрим процесс компиляции этого кода:

I) Встречаем объявление переменной (ключевое слово var)

Создаем таблицу переменных по алгоритму:

а. Устанавливаем текущей переменной первую.
б. Берется имя текущей переменной.
в. Ищем это имя в таблице переменных.
г. Если имя найдено то выдаем сообщение об ошибке "Multiple Declaration for <имя переменной>" и останавливаемся.
д. Если имя не найдено то заносим его в первую чистую строку таблицы. (Здесь же определяется ее размер и адрес в статической памяти)
е. Берем в качестве текущей переменной следующую переменную (если таковой нет то алгоритм завершает работу)и переходим к шагу б.

Таким образом получаем следующую таблицу переменных:
 --------------------------------------------------
| имя  |   размер   |   адрес в статической памяти |
|--------------------------------------------------|
|a     |     4      |             0                |
|b     |     4      |             4                |
|c     |     8      |             8                |
|d     |     8      |             16               |
 --------------------------------------------------
II) Разбор основного кода:
/*
 Обозначим операции след образом:
 (периведение типов не учитывается)

 subra  код регистра, адрес вычитаемого - операция вычитания с указанием кода регистра и адреса вычитаемого
                                          (SUB from <R>egister <A>ddres)
 movra  код регистра,адрес источника    - перемещение числа из источника в региcтр с указанием адреса 
                                          источника (MOV to <R>egister from <A>ddres)
 movar  адрес приемника, код регистра   - перемещение числа из регитра в приемник 
                                          (MOV to <A>ddres from <R>egister)
 movac  адрес приемника, константа      - перемещение  константы  в  приемник
                                          (MOV to <A>ddres <C>onst)
*/
Сначала надо все перевести в префиксную форму получаем код:
=(a,1)
=(b,3)
=(c,-(a,b))
=(d,-(b,d))
Далее начинаем разбор.
Когда встречаем операцию то пишем в выходной файл ее код.
Когда встречаем имя переменной то ищем есть ли она в таблице. Если нет, то выдаем сообщение об ошибке "Undefined symbol <имя переменной>", если есть, то пишем в выходной файл ее адрес (здесь же проверяем сколько операндов у текущей операции)

таким образом получаем код:
movac  0,1  // a=1
movac  4,3  // b=3
movra AX,0  // в AX помещаем a
subra AX,4  // a-b в Ax
movar 8,AX  // c=AX (c=a-b)

movra AX,4  // в AX помещаем b
subra AX,16 // b-d в AX
movar 16,AX // d=AX (d=b-d)
А вот как распределена статическая память
байты\биты  01234567
            --------
 0         |        |
 1         |        |- переменная a - 4 байта
 2         |        |
 3         |________|
 4         |        |
 5         |        |- переменная b - 4 байта
 6         |        |
 7         |________|
 8         |        |
 9         |        |
10         |        |
11         |        |- переменная с - 8 байт
12         |        |
13         |        |
14         |        |
15         |________|
16         |        |
17         |        |
18         |        |
19         |        |- переменная d - 8 баит
20         |        |
21         |        |
22         |        |
23         |________|
24         |        |
25         |        |- свободная память  (динамическая память, она же куча)
 .
 .
 .
На этом пока все.

Eternal Shield ([email protected])
Gamma ([email protected])
G3nius ([email protected])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
+-----[content]-----------------------------------------------------------------------------------------------------------------------[mail us]-----+