Пример регистрового соглашения вызова процедуры

Использование регистрового (быстрого) типа вызова

Трансляция.

Пример подключения объектного модуля к программе на Delphi.

Delphi 5.0

Так как строки Паскаль понимает иначе, чем Си, в качестве строк возьмём символьный массив. Директива stdcall используется и здесь.

{ программа COPYD.PAS, использующая ассемблер путем подключения объектного модуля } program Project2;uses SysUtils;{$APPTYPE CONSOLE}{$L 'copy.OBJ'}procedure COPYSTR(s1,s2: PChar); stdcall; EXTERNAL;var s1,s2: array[1..30] of char;begin s2[1] ='P'; s2[2] ='r'; s2[3] ='i'; s2[4] ='v'; s2[5] ='e'; s2[6] ='t'; s2[7] = char(0); COPYSTR(addr(s1[1]),addr(s2[1])); Writeln(s1);end.
; файл proc.asm.386P.MODEL FLAT, stdcallPUBLIC COPYSTR; плоская модельCODE SEGMENT DWORD PUBLIC USE32 'CODE'; процедура копирования одной строки в другую; строка, куда копировать [EBP+08Н]; строка, что копировать [EBP+0CH]; не учитывает длину строки, куда производится копирование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 ENDPCODE ENDSEND

Необходимо подготовить объектный модуль (с помощью транслятора TASM32) и указать его в директиве {$L copy.obj} - далее транслятор сделает все сам.


В соответствии с таблицей в начале главы, регистровый тип вызова предполагает, что три первых параметра будут передаваться в регистрах (EAX,EDX,ECX), а остальные в стеке, как и в случае соглашения stdcall. При этом если стек был задействован, освобождение его возлагается на вызываемую процедуру.

В случае быстрого вызова транслятор Си добавляет к имени значок @ спереди, что необходимо учитывать в ассемблерном модуле.

#include <windows.h>#include <stdio.h>// файл ADDC.cpp// объявляется внешняя функция сложения четырех целых чиселextern "C" _fastcall ADDD(DWORD, DWORD, DWORD, DWORD);void main(){ DWORD a,b,c,d; a=1; b=2; c=3; d=4; printf("%lu\n",(DWORD *)ADDD(a,b,c,d)); ExitProcess(0);}
; файл add.asm.386P.MODEL FLAT, stdcallPUBLIC @ADDD; плоская модель_TEXT SEGMENT DWORD PUBLIC USE32 'CODE'; процедура возвращает сумму четырех параметров; передача параметров регистровая; первые три параметра в регистрах EAX,EDX,ECX; четвертый параметр в стеке, т.е. [ЕРВ+08Н]@ADDD PROC PUSH EBP MOV EBP,ESP ADD EAX,ECX ADD EAX,EDX ADD EAX,DWORD PTR [EBP+08H] POP EBP RET 4@ADDD ENDP_TEXT ENDSEND

Трансляция модулей:

– tasm32 /ml add.asm

– включаем add.obj в проект addc (Borland C++ 5.0)

Вызываемая ассемблерная процедура может содержать не только какие-то вспомогательные процедуры, но и работу с функциями API и ресурсами. Причем, ресурсы, разумеется, являются для всех модулей проекта общими. Можно иметь несколько файлов, задающих ресурсы, но главное, чтобы не совпадали имена и идентификаторы.



Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: