Обучающие курсы:

Обучение профессии "Разработчик C#" + стажировка в Mail.ru
Обучение профессии "Разработчик Python" + трудоустройство
Обучение профессии "Веб-разработчик" + стажировка в Mail.ru


Главная страница
Библиотека (скачать книги)
Скачать софт
Введение в программирование
Стандарты для C++
Уроки по C#
Уроки по Python
HTML
Веб-дизайн
Ассемблер в среде Windows
ActiveX
Javascript
Общее о Линукс
Линукс - подробно
Линукс - новое
Delphi
Паскаль для начинающих
Турбопаскаль
Новости
Партнеры
Наши предложения
Архив новостей





Если в ЕАХ возвращается константа INVALID_HANDLE_VALUE, ТО происходит выход из ассемблерного блока программы. При этом отображается соответствующее сообщение через вызов другой функции WIN API MessageBox. Если удалось создать файл, то в регистре ЕАХ возвращается целочисленный дескриптор файла, который используется при последующих файловых операциях.
После выполнения записи в файл необходимо его закрыть с помощью функции cioseHandie. Если, операция выполнена успешно, то в рабочем каталоге проекта будет находиться файл TEXTOUT с записанной строкой.
По завершению записи в файл необходимо освободить буфер памяти, на который указывает pBuf:
FreeMem(pBuf, lenBuf);
Количество записанных байт содержится в переменной bufWritten и отображается оператором
Edit2.Text -:= IntToStr(bufWritten);

6.8. Применение встроенного ассемблера в Microsoft Visual С++ .NET
Среда разработки Microsoft Visual С++ .NET включает в себя мощнейшие средства поддержки программирования на языке ассемблера. Любой блок ассемблерного кода, встречающийся в программе, должен начинаться с ключевого слова asm и заключаться в фигурные скобки, как, например:
_asm {
mov ЕАХ, vail
sub EAX, EBX
}

Можно применять альтернативную форму записи команд ассемблера в строку. Предыдущий фрагмент кода в этом случае будет выглядеть так: _asm mov ЕАХ, vail
_asm sub EAX, EBX

Допускается и третья форма написания ассемблерного кода — в одну строку: _asm mov ЕАХ, vail _asm sub EAX, EBX
Встроенный ассемблер С + + .NET является весьма эффективным средством оптимизации программ. Немного о терминологии. В языке С + + принято для определения отдельных подпрограмм использовать термин "функция", независимо от того, возвращает она результат или нет. В дальнейшем по тексту мы будем придерживаться этого определения.
У программистов, использующих ассемблер MASM, сразу может возникнуть вопрос: в какой мере среда разработки С + + .NET поддерживает синтаксис этого языка. Многие конструкции MASM, такие как DB, DW, DD, DQ, DF ИЛИ операторы DUP И THIS, не поддерживаются. Встроенный ассемблер не поддерживает и такие директивы, как STRUC, RECORD, WIDTH, MASK.

Операторы ассемблера LENGTH, SIZE ИЛИ TYPE ограничены в применении в Visual С++ .NET. Их нельзя применить с оператором DUP, поскольку для определения данных директивы DB, DW, DD, DQ И DF не используются. Однако их можно использовать для определения размеров переменных следующим образом:
• оператор LENGTH возвращает число элементов массива или единицу для обычных переменных;
• оператор S I Z E возвращает размер переменной языка С или С + + ;
• оператор TYPE возвращает размер переменной. Если переменная указывает на массив, то этот оператор возвращает размер одного элемента массива.

Внутри ассемблерного блока можно определять целочисленные константы, соответствующие правилам, принятым как в С + + , так и в ассемблере. Например, символ пробела может быть записан и как 0x20, и как 20h.
Допускается использование директивы define для определения констант.
Такое определение будет действовать как в ассемблерном блоке, так и в программе на С + + .
Что касается применения операторов С + + в ассемблерных блоках, то здесь есть некоторые нюансы. В блоке asm нельзя использовать специфические для языка С + + операторы. В то же время некоторые операторы совершенно по-разному трактуются в ассемблере и в С + + . Например, оператор квадратных скобок [] в С++ используется для указания размеров массива. Во встроенном ассемблере этот же оператор применяется для индексирования доступа к переменным.
Если неправильно применять операторы в блоке asm, то обнаружить ошибки в программе будет очень трудно.
Привем пример правильного и неправильного использования оператора квадратных скобок. Для этого разработаем приложение на С + + . NET.
Поместим на главную форму приложения три поля редактирования Edit, кнопку Button и три метки статического текста Label. Основная программа будет содержать функцию, написанную на встроенном ассемблере, и обработчик нажатия кнопки. В обработчике будет происходить визуализация вычислений, выполненных на ассемблере. Для тестирования возьмем 5-элементный массив целых чисел. Попробуем заменить в нем элемент с индексом 3 (четвертый по порядку) на число -115. Число выбрано произвольно. Замену выполним двумя способами, в обоих случаях будем блок _asm.
Для форматирования вывода и отображения элементов массива в полях редактирования понадобятся переменные типа c s t r i n g , которые мы свяжем с элементами Edit. Полю Editl (метка original) присвоим переменную iOrigin, ПОЛЮ Edit2 (метка Correct) ПРИСВОИМ iAsmCorr И ПОЛЮ Edit3 (метка wrong) — iAsmWrong. При нажатии на кнопку в полях редактирования будут отображены элементы исходного массива (Editl), элементы корректно преобразованного массива (Edit2) и элементы неправильно преобразованного массива (Edit3). Исходный текст обработчика нажатия кнопки, в котором выполняется обработка массива, представлен в листинге 6.37.
Листинг 6.37. Программа, демонстрирующая применение оператора скобки
#include <string.h>
#define NUM_BYTES 4
void CUSINGOPERATORSIN_ASMBLOCKDlg::OnBnClickedButtonl()
// TODO: Add your control notification handler code here
int arr[5] = {4, 0, 9, -7, 50};
int arrw[5], arret5];
memcpy(arrw, arr, NUM_BYTES * 5);
memcpy(arrc, arr, NUM_BYTES * 5);
int* parr = arr;
int isize = sizeof(arr) / 4;
int cnt;
CString stmp;
stmp.Empty;
for (cnt = 0; cnt < isize; cnt++)
{
stmp.Format("%d", *parr);
iOrigin = iOrigin + " " + stmp;
parr++;
};
parr = arrc;
_asm {
mov EAX, -115
mov arrc[3 * TYPE int], EAX
};
stmp.Empty;
for (cnt = 0; cnt < isize; cnt++)
{
stmp.Format("%d", *parr);
iAsmCorr = iAsmCorr + " " + stmp;
parr++;
};
498 Гпава 6
parr = arrw;
_asm {
mov EAX, -115
mov arrw[3], EAX
};
stmp.Empty;
for (int cnt = 0; cnt < isize; cnt++)
{
stmp.Format("%d", *parr);
iAsmWrong = iAsmWrong + " " + stmp;
parr++;
};
UpdateData(FALSE);


Проведем анализ программного кода обработчика. В начале программы создается две копии исходного массива с помощью операторов:
memcpy(arrw, arr, NUM_BYTES * 5);
memcpy(arrc, arr, NUM_BYTES *<5);


 
 
 

Библиотека программиста. 2009.
Администратор: admin@programmer-lib.ru