Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции / GL18.doc
Скачиваний:
16
Добавлен:
20.05.2014
Размер:
73.22 Кб
Скачать

Использование __fastcall

Последний тип вызова __fastcall. Аргументы передаются в ECX и EDX. Остальные заталкиваются в стек справа налево. За счет использования регистров передача параметров ускоряется. Стек очищает функция. (По-прежнему включена оптимизация).

функция main

00401030 push 1042h

00401035 mov edx,15h

0040103A mov cl,61h

0040103C call 00401000

подпрограмма

00401000 mov eax,dword ptr [esp+4]

00401004 inc eax

00401005 inc edx

00401006 inc cl

00401008 push eax

00401009 movsx edx,dx

0040100C movsx eax,cl

0040100F push edx

00401010 push eax

00401011 push 406030h

00401016 call 00401050

0040101B add esp,10h

0040101E ret 4

Мы видим, что через регистры передаются первые два параметра. Остальные параметры (в нашем случае всего один) передаются через стек.

Объединение программы на Си и подпрограммы на языке Ассемблера в среде VC++

Недостаток включения ассемблерного кода в текст программы на Си с помощью директивы __asm: отключается оптимизация, нет переносимости программы на другие платформы. Поэтому представляет интерес следующий подход: помещать подпрограмму на языке Ассемблера в отдельный файл и отдельно ее ассемблировать. Далее с помощью компоновщика объединять файлы.

Рассмотрим пример

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

m.c

include <stdio.h>

int power2( int num, int power );

void main()

{

printf( "3 times 2 to the power of 5 is %d\n", \

power2( 3, 5) );

}

Подпрограмма осуществляет умножение числа num на 2^power с помощью нескольких сдвигов влево.

f.asm

.386

.MODEL flat,C

PUBLIC power2

.CODE

power2 PROC

ARG num:dword, power:dword

mov eax, num

mov ecx, power

shl eax, cl

ret

power2 ENDP

END

Нам нужно получить объектный файл в 32-разрядном формате, поэтому нужно воспользоваться не tasm.exe, а tasm32.exe. Заодно посмотрим листинг этой программы.

c:\tasm\bin\tasm32/l/mx f.asm

f.lst

1 .386

2 00000000 .MODEL flat,C

3 PUBLIC power2

4 00000000 .CODE

5 00000000 power2 PROC

6 ARG num:dword, power:dword

1 7 00000000 C8 0000 00 ENTERD 00000h,0

1 8 00000004 8B 45 08 mov eax, num

9 00000007 8B 4D 0C mov ecx, power

10 0000000A D3 E0 shl eax, cl

1 11 0000000C C9 LEAVED

1 12 0000000D C3 RET 00000h

13 0000000E power2 ENDP

  1. END

num Number [FLAT:EBP+0008]

power Number [FLAT:EBP+000C]

power2 (_power2) Near32 FLAT:0000

Groups & Segments Bit Size Align Combine Class

DGROUP Group

_DATA 32 0000 Dword Public DATA

FLAT Group

_TEXT 32 000E Dword Public CODE

При построении проекта мы воспользуемся командой Project/ Add to Project/ Files и добавим файл f.obj. При компоновке мы получим предупреждение:

f.OBJ : warning LNK4033: converting object format from OMF to COFF

The format of the object file is OMF. This tool requires COFF input. To permanently convert the file, run EDITBIN on the file with no options.

Это означает следующее: tasm32 генерирует объектный файл в формате OMF — Object Module Format. Фирма Microsoft разработала собственный формат обьектных файлов COFF — Common Object File Format. Компоновщик предварительно преобразует один формат в другой.

При запуске программа выдает 96 (= 3 * 32)

Вот что мы увидим в окне Disassembly

00401000 push 5

00401002 push 3

00401004 call 00401020

00401009 push eax

0040100A push 406030h

0040100F call 0040102E

00401014 add esp,10h

00401017 ret

00401018 nop

0040101F nop

00401020 enter 0,0

00401024 mov eax,dword ptr [ebp+8]

00401027 mov ecx,dword ptr [ebp+0Ch]

0040102A shl eax,cl

0040102C leave

0040102D ret

К сожалению, если мы используем tasm для создания объектного файла, мы не можем использовать отладочную информацию. Среда VC++ "не понимает" отладочную информацию, включаемую tasm в объектный файл. Поэтому лучше использовать MASM фирмы Microsoft.

ml /Cx /coff /Zi /c /Fl f.asm

Получим файлы f.obj и f.lst. Расшифруем используемые ключи:

/Cx Preserve case in publics, externs (Сохранить регистр букв во внешних именах)

/coff Generate COFF format object file (Генерировать объектный файл в COFF-формате)

/Zi Add symbolic debug info (Добавить отладочную информацию)

/c Assemble without linking (Только ассемблировать, не компоновать)

/Fl Generate listing (Генерировать файл листинга)

Соседние файлы в папке Лекции