Шаг 89.
Передача параметров через регистры

    На этом шаге мы рассмотрим передачу параметров через регистры.

    На этом шаге используется другой тип вызова - быстрый, или регистровый. В соответствии с таблицей 1 шага 85, этот тип вызова предполагает, что три первых параметра будут передаваться в регистрах (ЕАХ, EDX, ECX), а остальные в стеке, как и в случае соглашения stdcall. При этом если стек был задействован, освобождение его возлагается на вызываемую процедуру. Есть еще один нюанс. В случае быстрого вызова транслятор С добавляет к имени символ @ спереди, что мы естественно учитываем в ассемблерном модуле.


    Пример регистрового соглашения вызова процедуры. Файл addc.cpp:
#include <windows.h>
#include <stdio.h>
//Объявляется внешняя функция сложения четырех чисел.
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, stdcall 
PUBLIC @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 ENDS 
      END
Тексты этих файлов можно взять здесь.

    Трансляция модулей выполняется так:

    tasm32  /ml add.asm

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

    На следующем шаге мы рассмотрим вызовы API.




Предыдущий шаг Содержание Следующий шаг