В ассемблерном модуле вызываемая процедура должна быть дополнительно объявлена при помощи директивы PUBLIC.
Взаимодействие ассемблерных модулей с модулями, написанными на языках высокого уровня
Выполнить трансляцию модуля modul2.asm и получить объектный модуль modul2.obj;
Выполнить трансляцию модуля modul1.asm и получить объектный модуль modul1.obj;
Пример использования директив extrn и public на схеме связи двух модулей Модуль1.asm и Модуль2.asm.
; -------------------------- Модуль 1 ------------------------
masm
model small
.stack 100h
.data
… …
.code
My_proc_1 proc
…
My_proc_1 endp
My_proc_2 proc
…
My_proc_2 endp
; -----Объявляем процедуру My_proc_1 видимой извне ---------
public My_proc_1
start:
….
….
end start
; -------------------------- Модуль 2 ------------------------
masm
model small
.stack 100h
.data
… …
.code
Extrn my_proc_1 ; объявляем процедуру my_proc_1 внешней
start:
….
….
call my_proc_1 ; вызов my_proc_1 из модуля 1
end star
Если необходимо собрать два ассемблерных модуля, например modul1.asm и modul2.asm в один исполняемый модуль, необходимо:
6) 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 предполагает, что стек освобождается в вызываемой процедуре.
Пример использования процедуры из внешнего модуля. Используется транслятор 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 L1L2: MOV EAX,DWORD PTR [EBP+08H] POP EBP RET 8COPYSTR ENDP_TEXT ENDSEND