Тема 3.6 Совместимость с языками высокого уровня
Тема 3. 6 Совместимость с языками высокого уровня
Существуют следующие формы комбинирования программ на языках высокого уровня с ассемблером:
Использование ассемблерных вставок (встроенный ассемблер, режим inline). Ассемблерные коды в виде команд ассемблера вставляются в текст программы на языке высокого уровня. Компилятор языка распознает их как команды ассемблера и без изменений включает в формируемый им объектный код. Эта форма удобна, если надо вставить небольшой фрагмент.
Использование внешних процедур и функций. Это более универсальная форма комбинирования. У нее есть ряд преимуществ:
— написание и отладку программ можно производить независимо;
— написанные подпрограммы можно использовать в других проектах;
— облегчаются модификация и сопровождение подпрограмм.
Встроенный ассемблер
При написании ассемблерных вставок используется следующий синтаксис:
_asm КодОперации операнды ; // комментарии
КодОперации задает команду ассемблера,
операнды – это операнды команды.
В конце записывается;, как и в любой команде языка Си.
Комментарии записываются в той форме, которая принята для языка Си.
Если требуется в текст программы на языке Си вставить несколько идущих подряд команд ассемблера, то их объединяют в блок:
_asm
{
текст программы на ассемблере; комментарии
}
Внутри блока текст программы пишется с использованием синтаксиса ассемблера, при необходимости можно использовать метки и идентификаторы. Комментарии в этом случае можно записывать как после;, так и после //.
Пример Даны целые числа а и b. Вычислить выражение a+5b.
Для вывода приглашений Введите a: и Введите b: используем функцию CharToOem(_T(«Введите «), s),
где s – указатель на строку, которая перекодирует русскоязычные сообщения.
#include < stdio. h>
#include < windows. h>
#include < tchar. h>
void main()
{
char s[20];
int a, b, sum;
CharToOem(_T(«Введите «), s);
printf(«%s a: «, s);
scanf(«%d», & a);
printf(«%s b: «, s);
scanf(«%d», & b);
_asm
{
mov eax, a;
mov ecx, 5
m: add eax, b
loop m
mov sum, eax
}
printf(«\n %d + 5*%d = %d», a, b, sum);
getchar(); getchar();
}
Для компоновки и запуска программы создаем проект как описано в разделе Создание консольных приложений.
Проект будет содержать 1 файл исходного кода с расширением cpp.
Результат выполнения программы:

Использование внешних процедур
Для связи посредством внешних процедур создается многофайловая программа. При этом в общем случае возможны два варианта вызова:
программа на языке высокого уровня вызывает процедуру на языке ассемблера;
программа на языке ассемблера вызывает процедуру на языке высокого уровня.
Рассмотрим более подробно первый вариант.
В таблице ниже представлены основные соглашения по передаче параметров в процедуру.
В программах, написанных на языке ассемблера, используется соглашение передачи параметров stdcall. Однако по сути получение и передача параметров в языке ассемблера производится явно, без помощи транслятора.
Тема 3. 7 Оптимизация алгоритма смешивания изображений с помощью технологии ММХ
AssemblerВыделить код
|
| . 586
. mmx
. model flat, stdcall
include c: \masm32\include\windows. inc
include c: \masm32\include\kernel32. inc
includelib c: \masm32\lib\kernel32. lib
include c: \masm32\include\user32. inc
includelib c: \masm32\lib\user32. lib
include c: \masm32\include\gdi32. inc
includelib c: \masm32\lib\gdi32. lib
; Константа, обозначающая допустимую границу фильтра
EdgeDist=30
. data
SrcImageName db 'c: \windows\winnt.bmp', 0 ; изображение - источник
NewImageName db " c: \output.bmp", 0 ; изображение - результат
ErrLdImage db 'Error loading image', 0
ErrFileWrite db " Can't write to file", 0
CmpDword dd EdgeDist*EdgeDist
AndDword dd 0FFFFFFh
; данные две структуры запишутся в .bmp файл как заголовок
BmpHeader BITMAPFILEHEADER < " MB", 0, 0, 0, size BITMAPFILEHEADER + size BITMAPINFOHEADER>
ImgHdr BITMAPINFO < >
pImgBits dd? ; указатель на массив пикселей изображения
. code
start:
invoke CreateCompatibleDC, 0
xchg eax, ebx
; загрузим изображение - источник
invoke LoadImageA, 0, offset SrcImageName, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE
xchg eax, edi
or edi, edi
jnz ImgLoaded
invoke MessageBox, 0, offset ErrLdImage, offset SrcImageName, MB_OK or MB_ICONERROR
invoke ExitProcess, 0
ImgLoaded:
mov esi, offset ImgHdr
assume esi: ptr BITMAPINFOHEADER
; получим информацию о изображении (ширину и высоту)
invoke GetDIBits, ebx, edi, 0, 0, 0, esi, DIB_RGB_COLORS
mov eax, [esi]. biHeight
IsTopDown:
neg eax
or eax, eax
js IsTopDown
mov [esi]. biHeight, eax
mul [esi]. biWidth
shl eax, 2
; выделим память для массива пикселей изображения, размером (высота*ширина*4)
invoke LocalAlloc, LMEM_FIXED, eax
mov [pImgBits], eax
mov [esi]. biBitCount, 32
mov [esi]. biCompression, 0
; получим пиксели изображения в выделенную память.
invoke GetDIBits, ebx, edi, 0, [esi]. biHeight, eax, esi, DIB_RGB_COLORS
mov [esi]. biSizeImage, 0
invoke DeleteObject, edi
invoke DeleteDC, ebx
dec dword ptr [esi]. biHeight
mov ebx, [esi]. biWidth
lea ecx, [ebx-1]
mov edx, [esi]. biHeight
assume esi: nothing
mov esi, [pImgBits]
movd mm7, [CmpDword]
movd mm6, [AndDword]
pxor mm0, mm0
; цикл проверки изображения на границы. esi - адрес массива с цветами изображения
align 10h
CopyNextLine:
CopyNextPixel:
movd mm1, dword ptr [esi] ; mm1= 0rgb
punpcklbw mm1, mm0 ; mm1=0000 00r 00g 00b
movq mm2, mm1 ; mm2=mm1
| | |
Воспользуйтесь поиском по сайту: