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

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


Главная страница
Библиотека (скачать книги)
Скачать софт
Введение в программирование
Стандарты для 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) ;
}


 
 
 

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