Скачиваний:
10
Добавлен:
01.05.2014
Размер:
159.74 Кб
Скачать
    1. Описание перевода операций по работе с метками

КомандаПОЛИЗ

Перевод в ассемблер

Пояснение

@DEFL

<имя метки>:

Предусловие:

В промежуточном стеке верхний элемент является меткой.

Вытолкнуть из промежуточного стека элемент, содержащий <имя метки>.

@JMP

jmp <имя метки>

Предусловие:

В промежуточном стеке верхний элемент является меткой.

Вытолкнуть из промежуточного стека элемент, содержащий <имя метки>.

@JMPF

pop eax

cmp eax, 1

jne <имя метки>

Предусловие:

В промежуточном стеке верхний элемент является переменной логического типа (4 байта, 0 – если false, 1 – еслиtrue), следующий за верхним элемент является меткой.

Вытолкнуть из промежуточного стека элемент. Вытолкнуть из промежуточного стека элемент, содержащий <имя метки>.

Постусловие:

Данные в регистре eaxпотеряны.

    1. Описание перевода операций по работе с памятью

КомандаПОЛИЗ

Перевод в ассемблер

Пояснение

@SET

push <размер типа в байтах>

call __copy_memory

add esp, 12

Предусловие:

Оба верхних элемента в промежуточном стеке являются указателями на переменные.

Узнать тип, на который указывают указатели, и определить его <размер в байтах>. Вытолкнуть из промежуточного стека два элемента.

Постусловие:

Содержимое памяти по данным указателям идентично.

__set_integer_variable

Предусловие:

Верхний элемент в промежуточном стеке является целочисленным значением. Следующий за ним элемент является указателем на целочисленную переменную.

Вытолкнуть из промежуточного стека два элемента.

Постусловие:

Значение целого числа по данному указателю равно данному выражению.

__set_rational_variable

Предусловие:

Верхний элемент в промежуточном стеке является рациональным значением. Следующий за ним элемент является указателем на рациональную переменную.

Вытолкнуть из промежуточного стека два элемента.

Постусловие:

Значение рационального числа по данному указателю равно данному выражению.

Пояснение:__copy_memory– это функция на языке ассемблера, которая выполняет копирование данных. Данная функция принадлежит библиотеке функций и макросов, которая была предварительно написана для более удобной трансляции.

Вызов функции соответствует конвенции вызовов stdcall, принятой вC. По этой конвенции стек очищает тот же, кто кладет в него параметры – в данном случае командаaddesp, 12 – выталкивает из стека три двойных слова.

Более подробное описание некоторых макросов и функций содержится в приложении.

Команда

ПОЛИЗ

Перевод в ассемблер

Пояснение

@SUBS

pop eax

mov eax, 1

xor ebx, ebx

xor ecx, ecx

xor edx, edx

k – 1 раз в порядке от младших индексов к старшим вывести:

pop ebx

sub ebx,

<левая граница типа индекса>

push eax

imul ebx

add ecx, eax

pop eax

mov ebx,

<диапазон значений индекса>

imul ebx

mov eax, ecx

mov ebx, <размер индексируемого элемента>

imul ebx

pop edx

add edx, eax

push edx

Предусловие:

Верхний элемент является целочисленной константой k, определяющей количество операндов. Далее следуют (k–1) целочисленных значений и указатель на разыменовываемую переменную.

Вытолкнуть из промежуточного стека (k+1) элемент. Итеративно посчитать адрес смещения.

Постусловие:

Данные в регистрах eax,ebx,ecx,edxбудут потеряны.

На вершине стека исполнения находится корректный указатель на элемент массива соответствующий индексации.

Пояснение:

Обозначим за M= <размер индексируемого элемента>, заCi= <указанныйi-ый индекс>, заLi= <левая границаi-го индекса>, заRi= <правая границаi-го индекса>. Тогда,Si= <ширинаi-го индекса> =Ri–Li+ 1.

Например, рассмотрим массив:

var

a : array [1..10, 2..20, 3..40] of integer;

и индексацию к нему:

a[10, 19]

Тогда, каждый элемент, который индексирован по первым двум индексам, сам представляет собой массив типа array[3..40]ofinteger, поэтому

M = sizeof(array[3..40] of integer) = 38 * sizeof(integer) =

= 38 * 4 = 152 (байта)

Указано два индекса, 10 и 19, поэтому C1=10, аC2=19.

Левые и правые границы, соответственно, L1=1,L2=2,R1=10,R2=20.

Отсюда ширины индексов, S1=10,S2=19.

В общем случае, полное смещение в байтах, при индексации по kиндексам вычисляется по формуле:

M * ((C1 – L1) * S2 * S3 * … * SK + (C2 – L2) * S3 * … SK+ …

+ (CK – LK))

Генерируемый код на ассемблере вычисляет эту формулу итеративно при известных параметрах индексов.

Описание перевода арифметических операций.

Команда

ПОЛИЗ

Перевод в ассемблер

Пояснение

@ADDINT

call __add_integer

add esp, 4

Предусловие:

Верхние два элемента являются целочисленными значениями.

Вытолкнуть из промежуточного стека два элемента. Положить в промежуточный стек результат операции в виде целочисленного значения.

Постусловие:

На вершине стека исполнения находится целочисленное значение, соответствующее результату операции.

@SUBINT

call __sub_integer

add esp, 4

@MULINT

call __mul_integer

add esp, 4

@DIVINT

call _div_integer

add esp, 4

@NEGINT

__negate_integer

Предусловие:

На вершине стека находится элемент, являющийся целочисленным значением.

Вытолкнуть из промежуточного стека элемент. Положить в промежуточный стек результат операции в виде целочисленного значения.

Постусловие:

На вершине стека исполнения находится целочисленное значение, соответствующее результату операции.

@INC

__increment_integer_variable

Предусловие:

На вершине стека находится элемент, являющийся указателем на целочисленное значение.

Вытолкнуть из промежуточного стека элемент.

Постусловие:

Элемент, находящийся по данному указателю, был увеличен на единицу.

@DEC

__decrement_integer_variable

Предусловие:

На вершине стека находится элемент, являющийся указателем на целочисленное значение.

Вытолкнуть из промежуточного стека элемент.

Постусловие:

Элемент, находящийся по данному указателю, был уменьшен на единицу.

Абсолютно аналогично транслируются бинарные операции с рациональными числами @ADDRAT, @SUBRAT, @MULRAT, @DIVRAT, @COMMONи унарные @NEGRAT, @FRAC, @INT, и @SIMPLIFY.

Также транслируются бинарные операции с логическим типом @AND, @ORи унарная @NOT. Логический тип рассматривается как целочисленный, принимающий значения 0 (false) или 1 (true).

Бинарные операции сравнений рациональных и целых чисел @=INT, @=RAT, @>INT, @>RAT, @<INT, @<RAT, @>=INT, @>=RAT, @<=INT, @<=RAT, @<>INT, @<>RATтранслируются аналогично.

Все они принимают в качестве параметров значения и кладут в стек результирующие значения.

Команда

ПОЛИЗ

Перевод в ассемблер

Пояснение

@NUMERATOR

__numerator_rational_variable

Предусловие:

Верхний элемент является указателем на рациональное число.

Вытолкнуть из промежуточного стека элемент. Положить в промежуточный стек результат операции в виде указателя на целое число.

Постусловие:

На вершине стека исполнения находится указатель, соответствующий результату операции (указатель на числитель или указатель на знаменатель рационального числа).

@DENOMINATOR

__denominator_rational_variable

@ITOR

__integer_to_rational

Предусловие:

Верхний элемент является целочисленным значением.

Вытолкнуть из промежуточного стека элемент. Положить в промежуточный стек результат операции в виде рационального значения.

Постусловие:

На вершине стека исполнения находится приведенное рациональное значение.

@ITOR2

pop eax

pop ebx

(возможное разыменовывание указателя)

__integer_to_rational

push ebx

push eax

Предусловие:

На вершине стека находится рациональное значение, следующий за ним элемент представляет собой целочисленное значение.

Вытолкнуть из промежуточного стека элемент и сохранить его, изменить тип вершины стека с целочисленного значения на рациональное значение. Положить сохраненный элемент на вершину стека.

Постусловие: первые два элемента стека представляют собой рациональные значения.

@INPUT

call __input_integer_variable

add esp, 4

Предусловие:

На вершине стека находится указатель

на целое число.

Вытолкнуть из промежуточного стека элемент.

Постусловие:

Содержимое памяти по данному указателю соответствует введенному с консоли знаковому целому числу.

__input_rational_variable

Предусловие:

На вершине стека находится указатель

на рациональное число.

Вытолкнуть из промежуточного стека элемент.

Постусловие:

Содержимое памяти по данному указателю соответствует двум введенным через enterс консоли знаковым целым числам – числителю и знаменателю рационального числа.

@OUTPUT

call __output_integer

add esp, 4

Предусловие:

На вершине стека находится целочисленное значение..

Вытолкнуть из промежуточного стека элемент.

Постусловие:

В консоль выведено целое знаковое число.

call __output_rational

add esp, 8

Предусловие:

На вершине стека находится рациональное значение.

Вытолкнуть из промежуточного стека элемент.

Постусловие:

В консоль выведено рациональное число в формате <числитель>/<знаменатель>.

Замечание:

Когда речь идет о том, что на вершине стека находится рациональное значение – имеются в виду, два двойных слова, записанных последовательно – причем верхушка стека соответствует числителю, а следующий за верхушкой элемент – знаменателю.

Для того чтобы разыменовывать указатели дозначений, используются два макроса__evaluate_rationalи__evaluate_integer. Их код приведен в приложении.

Соседние файлы в папке Бяша