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





Здесь копируются байты, поэтому последний параметр функции memcpy равен количеству байт в массивах. Прототип функции определен в файле Встроенный ассемблер языков высокого уровня: принципы использования 499 string.h, поэтому в текст программы в раздел деклараций необходимо добавить строчку:
#include

В обработчике нажатия кнопки присутствуют три цикла for, которые подготавливают буферы переменных iOrigin, iAsmCorr и iAsmwrong для вывода элементов массивов в поля редактирования. Рассмотрим подробно, что происходит с массивами аггс и arrw при попытке заменить в них четвертый элемент. Для массива аггс запись числа —115 выполняется следующим образом:
parr = аггс; // инициализация указателя
_asm {
mov ЕАХ, -115 // запись числа в регистр ЕАХ
mov arrc[3 * TYPE int], EAX // запись содержимого EAX no адресу
// элемента с индексом 3 -(правильно!)

После выполнения этих команд в четвертом элементе массива находится — 115. Другая ситуация с массивом arrw. Запись по адресу четвертого элемента выполняется операторами:
parr = arrw;
_asm {
mov EAX, -115
mov arrw[3], EAX
};
// НЕПРАВИЛЬНАЯ КОМАНДА!

После выполнения этих команд будут перезаписаны четыре байта памяти, начиная с элемента с индексом 3. Поскольку 4-й байт является последним для первого элемента массива, а последующие (с 5 по 7-й) захватывают второе число в массиве, то в результате содержимое первых двух элементов массива будет разрушено
Ситуации, подобные этой, могут встретиться при работе со встроенным ассемблером С + + .NET, поэтому надо тщательно отслеживать все преобразования с применением ассемблера.
Как уже было сказано, в ассемблерном блоке можно ссылаться на любые символы языка С + + , хотя и существуют некоторые ограничения:
• в каждой ассемблерной команде может содержаться ссылка только на один символ (переменную, функцию или метку). Для использования нескольких символов в одной команде необходимо, чтобы все они применялись в выражениях типа LENGTH, TYPE И S I Z E ;
500 Гпава 6
• функции, на которые ссылаются команды ассемблерного блока, должны быть заранее объявлены в программе, иначе компилятор не сможет отличить ссылку на функцию от метки;
• в ассемблерном блоке нельзя использовать символы С++, которые схожи по написанию с директивами MASM;
• в ассемблерном блоке не распознаются структуры и объединения.

Наиболее ценной особенностью встроенного ассемблера С + + .NET является его способность распознавать и использовать переменные языка С++.
Если в модуле, где используется ассемблер, определены, например, переменные vail и vai2, то следующая ссылка в ассемблерном блоке будет корректной: _asm {
mov ЕАХ, vail
add ЕАХ, val2
}

Как известно, функции в языке С++ возвращают результат в основную программу, используя оператор return. Например, следующая функция (назовем ее Mulints) возвращает в основную программу значение il * i2 + юо (листинг 6.38).
j Листинг 6.38. Функция, возвращающая результат с помощью оператора r e t u r n | int CReturnValueinregisterEAXwithinlineassemblerDlg::MulInts(int il, int i2)
{
int valMul;
asm {
mov EAX, il
mov EBX, i2
mul EBX
xchg EAX, EDX
add EDX, 100
mov valMul, EDX
};
return valMul;
}

Встроенный ассемблер позволяет обходиться без оператора return при возвращении результата, используя для этого регистр ЕАХ. Та же самая функция Mui int s при определенных изменениях исходного текста может использовать такую возможность (листинг 6.39).
Листинг 6.39. функция, возвращающая результат в регистре ЕАХ
int CReturnValueinregisterEAXwithinlineassemblerDlg::MulInts(int il,
int i2)
{
_asm {
mov EAX, il
mov EBX, i2
mui EBX
add EAX, 100
};
}

Несмотря на то, что функция не возвращает результат через оператор return, компилятор не выдаст сообщение об ошибке.
При написании ассемблерного кода нет необходимости сохранять регистры ЕВХ, E S I и E D I . Однако если регистры используются в программе, то компилятор будет сохранять их при вызове функции и автоматически восстанавливать после выхода из нее. При частом вызове такой функции может несколько снизиться быстродействие.
Если ваша программа использует команды cid или std, то необходимо восстанавливать значение флага направления при выходе из функции.
После теории можно перейти к демонстрации возможностей встроенного ассемблера на примерах конкретных программ обработки числовых и текстовых данных. Начнем с примера вычисления суммы двух целых чисел il и i2. Создадим каркас приложения на базе диалогового окна и выполним некоторые дополнительные действия. Разместим на главной форме окна три поля редактирования Edit (для ввода двух целых чисел и вывода результата) и одну кнопку Button. Вычисление суммы чисел будет выполнять ассемблерная функция SumTwoInts.

Как известно, элементам управления в С + + .NET можно поставить в соответствие переменные того или иного типа. Манипуляции с элементами управления в этом случае могут выполняться через их переменные. Свяжем с элементом Editl переменную целого типа i _ n , а с элементом управления Edit2 — переменную i_i2. Элементу управления Edit3 поставим в соответствие переменную i _ n i 2 . После этого можно использовать все эти переменные в выражениях С++. Вычисление суммы выполняет функция SumTwoints, а ввод-вывод осуществляет обработчик нажатия кнопки. Фрагменты программного кода приведены в листинге 6.40.
Листинг 6.40. Вычисление суммы двух целых чисел и вывод результата int CSummationofTwoIntegersDlg::SumTwoints(int il, int i2)
{
_asm {
mov EAX, il
add EAX, i2
}
};
void CSummationofTwoIntegersDlg::OnBnClickedButtonl()
{
// TODO: Add your control notification handler code here
UpdateData(TRUE);
i_IH2 = SumTwoints (i_Il, i_l2) ;
UpdateData(FALSE);
}


 
 
 

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