Читайте также:
|
|
1. Постановка задачі для конкретного варіанта.
2. Блок-схема алгоритму виконання прикладу з детальним коментарем та описом роботи.
3. Лістинг програми та коментарі до всіх команд.
4. Рrint screen екрана 32-розрядного налагоджувача з виконанням програми та результатами виконання.
5. Короткий опис виконання програми.
6. Висновки за результатами роботи.
Приклад 12.7:
Проаналізувати масив даних з 10 елементів розміром у подвійне слово. Додавати елементи масиву доти, поки значення суми не перевищить 15. Зберегти номер елемента, на якому відбулося переповнення. Видати повідомлення на екран монітора (текстове або/чи числове).
Блок-схему алгоритму виконання прикладу наведено на рис. 12.9.
![]() |
Розв’язання прикладу 12.3 з використанням директив високого рівня, але поки без виведення даних, наведено у лістингу 12.9.
Лістинг 12.9:
title CopyRight by Rysovaniy A. N. rysov@rambler.ru
.386; директива визначення типу мікропроцесора
.model flat, stdcall; завдання лінійної моделі пам’яті
; та угоди ОС Windows
option casemap:none; відмінність малих та великих літер
.data; директива визначення даних
mas1 dd 1,4,5,4,6,7,3,8,2,10; масив чисел
len equ $-mas1; визначення кількості байтів в масиві
.code; директива початку сегмента даних
_start:; мітка початку програми з ім’ям _start
mov ecx,len; завантаження лічильника
shr ecx,2; визначення кількості подвійних слів
lea esi, mas1; завантаження адреси початку масиву
mov eax, [esi]; завантаження числа
m1:
.IF(eax<15); умова
mov ebx,[esi+4]; завантаження нового числа з масиву
add eax,ebx; додавання елементів
add esi,4; розрахунок адреси нового числа
add ebx,4; розрахунок адреси наступного числа
loop m1; перейти на m1, якщо ecx = 0
.ENDIF; закінчення директиви високого рівня
ret; повернення керування ОС
end _start; директива закінчення програми з ім’ям _start
У наведеній програмі при виникненні необхідності додавання двох чисел одного масиву слід використати додатковий регістр (для зберігання адреси другого числа). Таким регістром вибрано регістр ebx. Завантаження в цей регістр значення адреси другого числа виконується командою mov ebx,[esi+4].
У зв’язку з тим, що за завданням вибрано формат регістрів в 32 розряди (4 байти), для підготовки зчитування нових слів виконуються команди
add esi,4
add ebx,4.
Вікна налагоджувача після налагодження програми з лістингу 12.9 наведено на рис. 12.10.
![]() |
Для виконання другої частини роботи необхідно організувати виведення даних на екран. Для цього доцільно використати АРІ-функцію WriteConsoleA, фрагмент застосування якої може бути таким:
.386
.model flat, stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
BSIZE equ 15
.data; директива визначення даних
stdout dd?; дані для дескриптора виведення, що не визначені
buf db BSIZE dup(?); резервування пам’яті для буфера
frmt db "%d",0; завдання перетворення одного символу
cWritten dd?; комірки пам’яті для адрес
; символів виведення
...
.code; директива початку сегмента даних
_start:; мітка початку програми з ім’ям _start
...
invoke GetStdHandle, STD_OUTPUT_HANDLE; отриманого дескриптора
mov stdout, eax; запам’ятовування отриманого дескриптора
...
invoke wsprintf, \; АРІ-функція перетворення числа
ADDR buf, \; адреса буфера, куди буде записана посліднісьт символів
ADDR frmt, \; адреса рядка перетворення формату
edx; регістр, вміст якого перетворюється
invoke WriteConsoleA, \; АРІ-функція виведення на екран
stdout, \; дескриптор стандартного пристрою виведення
ADDR buf,\; адреса початку повідомлення
BSIZE, \; розмір повідомлення
ADDR cWritten, \; адреса, де зберігається число символів
NULL
invoke ExitProcess, 0; повернення керування ОС Windows
; та визволення ресурсів
end _start; директива закінчення програми з іменем _start
У цій програмі використовуються файли user32.inc і user32.lib, що зберігають інформацію про функцію wsprintf. Число параметрів цієї функції поки дорівнює трьом:
1. Параметр ADDR buf – це адреса буфера, куди буде записана послідовність символів. Пам’ять для буфера виділяється рядком buf db BSIZE dup(?), який резервує кількість байтів, заданих змінною BSIZE. Про резервування байтів пам’яті говорить слово dup – скорочене від англійського слова duplication (повторення). Знак питання, в дужках після dup, свідчить про те, що значення байтів наперед не визначене.
Розмір буфера, позначений ім’ям BSIZE, є реальним числом, яким асемблер замінить змінну BSIZE та яке задається рядком BSIZE equ 15.
2. Параметр ADDR ifmt – це адреса рядка формату, яка задає тип перетворення. Цей рядок складається з символів і завжди завершується нульовим байтом. Рядок “%d”,0 задає перетворення одного цілого числа в послідовність символів, а рядок “%d%d”,0 – перетворення двох чисел.
3. Параметр edx вказує функції wsprintf на те що число, яке потребує перетворення в послідовність символів, знаходиться, наприклад, у регістрі edx.
Процедура WriteConsoleA виводить ці символи на екран. За першим параметром цієї функції (stdout) перетворене у символ число виводиться через консоль, за другим (параметр ADDR buf) вказується адреса початку повідомлення, за третім (BSIZE) – розмір повідомлення, за четвертим (ADDR cWritten) – адреса ділянки пам’яті, де процедура WriteConsoleA зберігає число виведених на екран символів.
Приклад 12.8. Проаналізувати масив даних mas1 з 6 елементів. Підрахувати і зберегти в комірках пам’яті кількість елементів масиву, якщо їх значення менші або більші від першого елемента та дорівнюють останньому.
Лістинг 12.10:
.686; директива визначення типу мікропроцесора
.model flat,stdcall; завдання лінійної моделі пам`яті та угоди ОС Windows
option casemap:none; відмінність малих та великих літер
include C:\masm32\include\mcdsrv32.inc
include C:\masm32\include\windows.inc; файли структур, констант …
include C:\masm32\include\kernel32.inc; файли систем. функцій застосувань…
include C:\masm32\include\\user32.inc; файли інтерфейсу …
includelib C:\masm32\lib\mcdsrv32.lib
includelib C:\masm32\lib\kernel32.lib
includelib C:\masm32\lib\user32.lib
IDI_ICON EQU 1001
.data
_min dd 0
_max dd 0
_toj dd 0
_st1 db "ЛР7 Директиви умовного асемблювання",0
_st2 dd?,0
_mas1 dd 4,3,44,12,22,4
_El1 dd 4
ifmt db "Исходный массив:",0dh,0ah,\
"04 03 44 12 22 04",0dh,0ah,0ah,\
"Количество елементов, равных первому = %d",0dh,0ah,0ah,\
"Количество елементов меньших, чем первый = %d",0dh,0ah,0ah,\
"Количество елементов больших, чем первый = %d",0dh,0ah,0ah,\
"Автор: Гладких А.А., КІТ-39",0
params MSGBOXPARAMS <>
.code
_nach:
mov ecx,5
lea esi,_mas1
add esi,4
m1:
mov ebx,_El1
mov eax,dword ptr [esi]
.IF eax==ebx
add _toj,1
.ELSEIF eax > ebx
add _max,1
.ELSEIF eax < ebx
add _min,1
.ENDIF
add esi,4
loop m1
invoke wsprintf,ADDR _st2,ADDR ifmt,_toj,_min,_max
mov params.cbSize,SIZEOF MSGBOXPARAMS
mov params.hwndOwner,0
invoke GetModuleHandle,0
mov params.hInstance,eax
mov params.lpszText,offset _st2
mov params.lpszCaption,offset _st1
mov params.dwStyle,MB_USERICON
mov params.lpszIcon,IDI_ICON
mov params.dwContextHelpId,0
mov params.lpfnMsgBoxCallback,0
mov params.dwLanguageId,LANG_NEUTRAL
invoke MessageBoxIndirect,ADDR params
invoke ExitProcess,0; закінчення програми
end _nach
Результат виконання програми наведено на рис. 12.11.
![]() |
Література: Рисований О.М. Системне програмування [Текст]: підручник для студентів напрямку “Компютерна інженерія” вищих навчальних закладів. Видання друге: виправлено та доповнено – Х.: “Слово”, 2011. – 944 с.
Дата добавления: 2014-12-18; просмотров: 69 | Поможем написать вашу работу | Нарушение авторских прав |