- •Лекция №12. Процедуры в программах на ассемблере. Crc-код
- •1) Если имя – это имя переменной, то тип может принимать значения byte, word, dword, pword, fword, qword и tbyte;
- •3) Если имя – это имя константы, то тип должен быть abs.
- •Выполнить трансляцию модуля modul1.Asm и получить объектный модуль modul1.Obj;
- •Выполнить трансляцию модуля modul2.Asm и получить объектный модуль modul2.Obj;
- •Cкомпановать программу утилитой tlink командной строкой вида:
- •1) Используя последовательность из n команд рор хх.
- •2) Откорректировать регистр указателя стека sp на величину 2*n, например, командой
- •1) Сложение по правилам полиномиальной арифметики по модулю 2 (crc-арифметика), будет выполнено так (нет переносов):
- •2) Операция вычитания:
- •1) Согласование имен,
- •2) Согласование параметров,
- •3) Согласование вызовов.
- •Примеры
- •1) Пример использования директивы asm и команд сопроцессора в программе на языке Паскаль (Delphi 5.0).
- •3) Программа, которая использует функцию stdcall get_str_length с асемблерной вставкой, для нахождения длины asciiz-строки.
- •4) Программа, которая складывает два числа в десятичной системе исчисления и выдаёт результат тоже в десятичной системе исчисления. (Example2)
- •Выполнить трансляцию модуля modul1.Asm и получить объектный модуль modul1.Obj;
- •Выполнить трансляцию модуля modul2.Asm и получить объектный модуль modul2.Obj;
- •Cкомпановать программу утилитой tlink командной строкой вида:
- •4) В ассемблерном модуле вызываемая процедура должна быть дополнительно объявлена при помощи директивы public.
- •К имени процедуры в объектном модуле автоматически добавляется @8 (а не @0).
- •Ассемблер автоматически управляется со стеком.
- •3) Сложение двух целых чисел.
Лекция №12. Процедуры в программах на ассемблере. Crc-код
Процедуры в программах для DOS16
В языке ассемблера для формирования процедур как отдельных объектов существуют специальные директивы PROC/ENDP и машинная команда ret. Возможные варианты размещения процедур:
– в начале программы (до первой исполняемой команды);
– в конце (после команды, возвращающей управление операционной системе);
– промежуточный вариант, когда тело процедуры располагается внутри другой процедуры или основной программы. В этом случае необходимо предусмотреть обход процедуры с помощью команды безусловного перехода jmp;
– в другом модуле.
То есть главное, чтоб на процедуру не попадало управление.
С помощью специального механизма вызова процедуры появляется возможность сохранения информации о контексте (контекст – информация о состоянии программы в точке вызова процедуры) программы в точке вызова процедуры.
Есть две команды, осуществляющие работу с контекстом программы. Это команды call и ret:
– call[модификатор] имя_процедуры – вызов процедуры. Команда call, подобно jmp передаёт управление по адресу с символическим именем имя_процедуры, но при этом в стеке сохраняется адрес возврата. Адрес возврата – это адрес команды, следующей после команды call;
– ret [число] – возвратить управление вызывающей программе. Команда ret считывает адрес возврата из стека и загружает его в регистр cs и eip/ip тем самым возвращая управление на команду следующую в программе за командой call. [число] – необязательный параметр, обозначающий количество элементов, удаляемых из стека при возврате из процедуры.
Вызов процедуры командой call может быть:
– внутрисегментным (имеет тип near) и в качестве возврата команда call сохраняет в стек только содержимое регистра eip/ip;
– межсегментным (имеет тип far) и для осуществления возврата команда call заносит в стек содержимое регистров cs и eip/ip. Очерёдность такова: сначала в стек помещается регистр cs, а потом eip/ip.
При работе с процедурами, которые описаны в другом модуле, программа должна использовать две директивы TASM: extrn и public.
Директива extrn предназначена для объявления некоторого имени внешним по отношению к данному модулю.
Имя, которое будет использоваться в другом модуле, должно быть объявлено в директиве public.
Синтаксис этих директив следующий:
Extrn имя:тип, …, имя:тип
Public имя, …, имя
Здесь имя – идентификатор, определённый в другом модуле. В качестве идентификатора могут выступать:
– имена переменных, определённых директивами типа db, dw и т.п.;
– имена процедур;
– имена констант, определённых операторами = и equ
Возможные значения типов:
1) Если имя – это имя переменной, то тип может принимать значения byte, word, dword, pword, fword, qword и tbyte;
2) если имя – это имя процедуры, то для DOS тип может принимать значения near, far. В данном случае тип характеризует возможность обращения к процедуре из другого сегмента кода. По умолчанию тип принимает значение near (для DOS).