- •Лекция №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) Сложение двух целых чисел.
-
Выполнить трансляцию модуля modul1.Asm и получить объектный модуль modul1.Obj;
-
Выполнить трансляцию модуля modul2.Asm и получить объектный модуль modul2.Obj;
-
Cкомпановать программу утилитой tlink командной строкой вида:
tlink /v modul1.obj+ modul2.obj
В итоге будет создан исполняемый модуль modul1.obj и можно будет исследовать данный модуль в отладчике, но при этом в турбо дебагере можно будет увидеть только текст программы modul1. Для того, чтобы войти в вызываемую процедуру, необходимо нажимать клавишу F7. Обработка этой команды приведёт к открытию второго окна, в котором будет выведен текст вызванной процедуры.
Взаимодействие ассемблерных модулей с модулями, написанными на языках высокого уровня
Рассмотрим простой модуль на языке ассемблера, содержащий процедуру, копирующую одну строку в другую. Подсоединяем этот модуль к программам, написанным на языке Си и Паскаль, с использованием трех трансляторов: Borland C++, Visual C++, Delphi.
Borland C++ 5.0
1) В С++ функции, вызываемые из ассемблерного модуля объявляются при помощи модификаторов extern "С" и stdcall.
2) Если модуль на языке ассемблера транслируется с помощью транслятора TASM, проблемы с подчеркиванием не возникает.
3) Тип вызова stdcall предполагает, что стек освобождается в вызываемой процедуре.
4) В ассемблерном модуле вызываемая процедура должна быть дополнительно объявлена при помощи директивы public.
Пример использования процедуры из внешнего модуля. Используется транслятор BORLAND C++ 5.0.
// файл copyc.cpp
#include <windows.h>
#include <stdio.h>
extern "C" _stdcall COPYSTR(char *, char *);
void main()
{
char s1[100];
char *s2="Privet!";
printf("%s\n",(char *)COPYSTR(s1, s2));
ExitProcess(0);
}
; файл copy.asm
.386P
; эта процедура будет вызываться из внешнего модуля
PUBLIC COPYSTR
.MODEL FLAT, stdcall
_TEXT SEGMENT DWORD PUBLIC USE32 'CODE'
; процедура копирования одной строки в другую
; строка, куда копировать [EBP+08Н]
; строка, что копировать [EBP+0CН]
; не учитывает длину строки, куда производится копирование
COPYSTR PROC
PUSH EBP
MOV EBP,ESP
MOV ESI,DWORD PTR [EBP+0CH]
MOV EDI,DWORD PTR [EBP+08H]
L1:
MOV AL,BYTE PTR [ESI]
MOV BYTE PTR [EDI],AL
CMP AL,0
JE L2
INC ESI
INC EDI
JMP L1
L2:
MOV EAX,DWORD PTR [EBP+08H]
POP EBP
RET 8
COPYSTR ENDP
_TEXT ENDS
END
Трансляция модулей
1-й способ.
В начале TASM32 /ml copy.asm
Затем в проект Borland C++ включить файл copy.obj.
2-й способ.
В проект включить сразу файл copy.asm, тогда транслятор автоматически вызовет TASM32.EXE.
3-й способ. Трансляция из командной строки. Предварительно готовим командный файл copy. Содержимое файла:
copyc.cpp
copy.obj
Далее вызываем bcc32 @сору.
4-й способ. В командном файле вместо copy.obj помещаем файл copy.asm.
2) Visual C++ 6.0 (процедура копирования одной строки в другую).
Текст на языке C++ не изменится, а вот ассемблерный текст необходимо изменить.
Транслятор Си автоматически добавит в конец вызываемой функции @8. Для этого необходимо явно указать параметры при объявлении процедуры. После этого к имени COPYSTR транслятор добавит @8. При таком объявлении не нужно явно устанавливать регистр EBP и освобождать стек – это все автоматически сделает транслятор.
Модуль на языке ассемблера для компоновки с помощью пакета Visual C++ 6.0.
; файл proc.asm
.386P
.MODEL FLAT, stdcall
PUBLIC COPYSTR
; плоская модель
_TEXT SEGMENT DWORD PUBLIC USE32 'CODE'
; процедура копирования одной строки в другую
; строка, куда копировать [EBP+08H]
; строка, что копировать [EBP+0CH]
; не учитывает длину строки, куда производится копирование
; явное указывание параметров
COPYSTR PROC str1:DWORD, str2:DWORD
MOV ESI,str2 ; DWORD PTR [EBP+0CH]
MOV EDI,str1 ; DWORD PTR [EBP+08H]
L1:
MOV AL,BYTE PTR [ESI]
MOV BYTE PTR [EDI],AL
CMP AL,0
JE L2
INC ESI
INC EDI
JMP L1
L2:
MOV EAX,DWORD PTR [EBP+08H]
RET
COPYSTR ENDP
_TEXT ENDS
END
Явное указание параметров в заголовке процедуры приводит: