Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции / Лекция № 11 Использование ассемблера с языками высокого уровня.ppt
Скачиваний:
15
Добавлен:
07.08.2024
Размер:
346 Кб
Скачать
☆

Использование ассемблера с языками высокого уровня

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

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);

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

Использование ассемблера с языками высокого уровня

push a

call _some_proc@4

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

Например, нужно написать процедуру, возвращающую слово, находящееся по адресу 0040h:006Ch, в BIOS — счетчик сигналов системного таймера, который удобно использовать для инициализации генераторов случайных чисел.

Использование ассемблера с языками высокого уровня

Пример. 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;

Использование ассемблера с языками высокого уровня

Пример. 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].