Главная страница
Библиотека (скачать книги)
Скачать софт
Введение в программирование
Стандарты для C++
Уроки по C#
Уроки по Python
HTML
Веб-дизайн
Ассемблер в среде Windows
ActiveX
Javascript
Общее о Линукс
Линукс - подробно
Линукс - новое
Delphi
Паскаль для начинающих
Турбопаскаль
Новости
Партнеры
Наши предложения
Архив новостей
|
При написании исходного текста функции SumTwoints мы воспользовались
возможностью передачи результата вычислений в регистре ЕАХ. При передаче
параметров не нужно явно указывать размер операндов. По умолчанию
компилятор считает размер целочисленного операнда равным 4 байтам, поэтому
команды блока asm транслируются корректно. Первый оператор обработчика
нажатия кнопки:
UpdateData(TRUE) ;
обновляет значения переменных i _ n и i_i2 в соответствии с текущими
значениями элементов управления Editl и Edit2. Другими словами, если
пользователь ввел в окне Editl значение 34, а в окне Edit2 — 67, то после
выполнения оператора UpdateData(TRUE) ЭТИ значения будут присвоены
Встроенный ассемблер языков высокого уровня: принципы использования 503
переменным i l l и i_i2 соответственно. Выполнение следующего оператора:
i_Ill2 = SumTwoInts(i_Il, i_I2);
позволяет сохранить результат выполнения функции SumTwoInts в переменной
i_ni2. И, наконец, оператор:
UpdateData(FALSE);
обновляет текущее содержимое элементов управления в соответствии со
значениями их переменных.
Следующий пример — вычисление суммы элементов массива вещественных
чисел. Помимо демонстрации работы математического сопроцессора здесь
будет показано, как передавать результат выполнения функции через указатель.
На главной форме приложения разместим два поля редактирования Edit и
одну кнопку Button. В первом поле редактирования Editl выведем весь
массив вещественных чисел, а во втором поле Edit2 будет выведен результат
вычислений.
Свяжем с элементами управления Editl и Edit2 две переменные — sArray
и f_summa соответственно. Переменной s_Array присвоим строковый тип
c s t r i n g , а переменной f_summa — вещественный float.
Вычисление суммы элементов массива вещественных чисел выполним с
помощью функции sumReais. В качестве параметров эта функция принимает
адрес массива и его размер. Исходный текст этой функции и обработчика
нажатия кнопки приведен в листинге 6.41.
Листинг 6.41. Вычисление суммы элементов массива вещественных чисел и вывод результата
float* CSummaofRealsDlg::sumReals(float* farray, int If)
{
float fsum;
_asm (
mov ESI, farray
mov ECX, If
dec ECX
f init
fldz
fid [ESI]
next:
add ESI, 4
fadd [ESI]
loop next
fstp fsum
fwait
lea EAX, fsum
};
}
void CSummaofRealsDlg::OnBnClickedButtonl()
{
// TODO: Add your control notification handler code here
float farray[] = (2.4, 5.9, -4.12, 3.12,-8.45};
int fsize = sizeof(farray)/4;
CString stmp;
UpdateData(TRUE);
stmp.Empty;
for (int cnt = 0; cnt < fsize; cnt++)
{
stmp.Format("%.2f", farray[cnt]);
s_Array = s_Array + " " + stmp;
};
f_Summa = *sumReals(farray, fsize);
UpdateData(FALSE);
}
Как уже упоминалось, при вызове функции нет необходимости сохранять
регистр E S I . Поэтому в самом начале функции sumReals загружаем адрес
массива farray в регистр E S I , а его размер — в регистр ЕСХ:
mov ESI, farray
mov ECX, If
Адресом массива farray является указатель на первый элемент этого массива.
Содержимое регистра ЕСХ используется для организации вычисления в
цикле. Самое первое значение элемента массива загружается в вершину
стека сопроцессора с помощью команды:
fid [ESI]
В каждой операции цикла выполняется продвижение адреса к следующему
элементу массива и прибавляется значение последующего элемента к содержимому
вершины стека:
next:
add ESI, 4
fadd [ESI]
loop ' next
Результат суммирования сохраняется в локальной переменной fsum:
fstp fsum
Последняя команда ассемблерной функции:
lea ЕАХ, fsum
загружает адрес переменной fsum в регистр ЕАХ. ЭТОТ адрес функция возвращает
в основную программу.
В обработчике нажатия кнопки мы используем строковые переменные для
преобразования числовых значений в текстовый формат. Отложим рассмотрение
строк до следующих примеров, а сейчас проанализируем один оператор:
f_Summa = *sumReals(farray, fsize);
В этом операторе fsumma — переменная вещественного типа, а функция
sumReais возвращает адрес. В этом случае для получения значения по адресу
используется оператор раскрытия ссылки " * " перед адресным выражением,
в нашем случае перед идентификатором функции.
Первый параметр, передаваемый в функцию sumReais, — адрес массива. Он
может быть представлен в альтернативной форме. Как мы знаем, адрес массива
указывает на первый элемент, поэтому рассмотренный оператор можно
записать и в другой форме:
f_Summa = *sumReals(Sfarray[0], fsize);
где для представления первого параметра в корректной форме используется
оператор получения адреса "&".
В следующих примерах рассмотрим реализацию простых алгоритмов сортировки
и поиска максимального элемента. На этих примерах постараемся оценить
эффективность встроенного ассемблера для оптимизации программ.
Вначале рассмотрим механизм поиска максимального элемента в массиве
целых чисел. Используя стандартный мастер приложения, разработаем каркас
приложения на основе диалогового окна.
Разместим на главной форме приложения два поля редактирования Edit и
кнопку Button. Поиск максимального элемента целочисленного массива
будет выполнять функция findMax. В качестве параметров функция принимает
адрес массива и его размер. Результатом выполнения функции является
значение максимального элемента в массиве. Фрагменты кода функции
findMax и обработчика нажатия кнопки приведены в листинге 6.42.
Листинг 6.42. Вычисление максимального значения в массиве целых чисел и
вывод результата
int CFindMaximumlntegerinArrayDlg::findMax(int* pil, int sil)
{
int maxVal;
_asm {
mov EDI, pil
mov ECX, sil
mov EDX, [EDI]
mov maxVal, EDX
next:
add EDI, 4
mov EAX, [EDI]
cmp EAX, maxVal
j1 no_change
push EAX
pop maxVal
no_change:
loop next
ex:
mov EAX, maxVal
};
}
void CFindMaximumlntegerinArrayDlg::OnBnClickedButtonl()
{
// TODO: Add your control notification handler code here
CString si;
int il[] = {4, -6, 9, -7, 32, -90, 123};
int sil = sizeof(il)/4;
si.Empty;
for (int cnt = 0; cnt < sil; cnt++)
(
si. Format ("%d", p.l[cnt]);
s_Array = s_Array + " " + si;
};
i_Max = findMax(il, sil);
UpdateData(FALSE) ;
}
<< Назад В начало Далее >> |
|