Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции / Лекция № 10 Драйверы устройств в MS Windows.ppt
Скачиваний:
27
Добавлен:
07.08.2024
Размер:
425.98 Кб
Скачать

some_proc proc push bp

mov bp,sp ; создать стековый кадр

a equ [bp+4] ; определения параметров b equ [bp+6]

с equ [bp+8] d equ [bp+10] e equ [bp+12]

; текст процедуры, использующей параметры a, b, с, d, e pop bp

ret some_proc endp

Ассемблеры поддерживают и такой формат вызова при

помощи усложненной формы директивы proc с указанием языка С:

some_proc proc

С,а:word,b:word,с:word,d:word,e:word

;текст процедуры, использующей параметры a, b, с, d, e.

;Так как BP применяется как указатель стекового кадра,

;его использовать нельзя!

ret some_proc endp

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

можно не заполнять стек каждый раз заново:

push param2 push param1 call proc1 call proc2 add sp,4

эквивалентно

proc1(param1,param2);

proc2(param1,param2);

и это — одна из причин, почему компиляторы с языка С создают более компактный и быстрый код по сравнению с другими языками.

В таблице ниже представлены основные соглашения по передаче параметров в процедуру.

Соглашение

Параметры

Очистка стека

Регистры

register (fastcall)

 

 

EAX, EDX, ECX (Delphi)

(быстрый

Слева направо

Процедура

ECX, EDX (Visual C++ .NET)

или регистровый вызов)

 

 

 

 

 

pascal

Слева направо

Процедура

Нет

(конвенция языка Паскаль)

cdecl

Справа налево

Вызывающая

Нет

(конвенция С)

 

программа

 

stdcall

Справа налево

Процедура

Нет

(стандартный вызов)

 

 

 

Safecall

Справа налево

Процедура

Нет

Таблица объясняет соглашения о передаче параметров. Например, передача параметров stdcall отличается и от С, и от PASCAL-конвенций. Она применяется для всех системных функций Win32 API. Здесь параметры помещаются в стек в обратном порядке, как в С, но процедуры должны очищать стек сами, как в PASCAL.

Еще одно интересное отклонение от С-конвенции можно наблюдать в Watcom С. Этот компилятор использует регистры для ускорения работы, и параметры в функции передаются по возможности через регистры. Например, при вызове функции

some_proc(a,b,с,d,e,f);

первые четыре параметра передаются соответственно в (Е)АХ, (E)DX, (Е)ВХ, (Е)СХ, а только начиная с пятого, параметры помещают в стек в обычном обратном порядке:

e

equ

[bp+4]

f

equ

[bp+6]

Еще один важный момент - тип возвращаемых функцией данных. С точки зрения ассемблера здесь все просто: в регистре EAX возвращается значение, которое может быть либо числом, либо указателем на переменную или структуру. Если возвращаемое число типа WORD, то оно содержится в младшем слове регистра EAX.

Cогласование имен идентификаторов. Компиляторы Microsoft С (а также многие компиляторы в UNIX) изменяют названия процедур, чтобы отразить способ передачи параметров. Так, к названиям всех процедур, использующих С-конвенцию, приписывается символ подчеркивания. То есть, если в С-программе записано

some_proc();

то реально компилятор пишет call _some_proc

и это означает, что, если эта процедура написана на ассемблере, она должна называться именно _some_proc (или использовать сложную форму записи директивы proc).

Названия процедур, использующих stdcall, например, при создании DLL, искажаются еще более сложным образом: спереди к называнию процедуры добавляется символ подчеркивания, а сзади — символ @ и размер занимаемой параметрами области стека в байтах, (то есть в точности число, стоящее после команды ret в конце процедуры).

some_proc(a:word);

превращается в

Пример. C

int get_seed()

 

int seed;

 

{

 

_asm {

 

push

es

mov

ax,0040h

mov

es,ax

mov

ax,es:[006Ch]

mov

seed,ax

pop

es

};

return(seed);

};

В этих ситуациях ассемблерная программа может свободно пользоваться переменными из языка высокого уровня, так как они автоматически преобразуются в соответствующие выражения типа word ptr [bp+4].

Пример. Pascal

function get_seed:longint var

seed:longint begin

asm

push

es

mov

ax,0040h

mov

es,ax

mov

ax,es:[006Ch]

mov

seed,ax

pop

es

end; get_seed:=seed;

end;