МІНІСТЕРСТВО ОСВІТИ І НАУКИ УКРАЇНИ
НАЦІОНАЛЬНИЙ УНІВЕРСИТЕТ “ЛЬВІВСЬКА ПОЛІТЕХНІКА”
/
Кафедра ЕОМ
ЛАБОРАТОРНА РОБОТА № 4
Програмування задач лінійної структури. Обчислення виразів.
Мета: вивчити способи задання констант та змінних в Асемблері та набути навиків використання арифметичних команд над даними різного розміру.
Теоритичні відомості
Арифметичні операції в Асемблері
Для виконання даної роботи слід розглянути наступні команди арифметики: ADD ADC INC SUB SBB DEC CMP NEG MUL DIV
Команди ADD і SUB виконують додавання й віднімання байтів або слів, що містять двійкові дані. Віднімання виконується у комп’ютері по методу додавання із двійковим доповненням: для другого операнда встановлюються зворотні значення бітів і додається 1, а потім відбувається додавання з першим операндом. У всьому, крім першого кроку, операції додавання й віднімання ідентичні. Можливі п’ять ситуацій:
ADD / SUB регістр-регістр;
ADD / SUB пам'ять-регістр;
ADD / SUB регістр-пам'ять;
ADD / SUB регістр-безпосереднє значення;
ADD / SUB пам’ять-безпосереднє значення.
Команда ADC виконує додавання з врахуванням переносу. Тобто якщо прапорець CF має значення 1, то ця команда додає 1 до першого операнду, а вже потім додає другий операнд.
Команда SBB виконує віднімання з запозиченням. Тобто якщо прапорець CF має значення 1, то ця команда спочатку віднімає 1 від першого операнду, а вже потім віднімає від нього другий операнд.
Додавання багатобайтних чисел
Наведемо універсальну процедуру додавання двох чисел довільної розмірності, використовуючи додавання окремих слів.
При цьому слід: 1) забезпечити сусідство слів; 2) виконувати обробку від молодшого до старшого слова; 3) завантажити в регістр CX кількість слів, що будуть додаватися
Дія починається з додавання наймолодших полів, тобто тих слів, що розташовані в пам’яті за молодшими адресами. У першому циклі додаються ліві слова, а у другому - слова, розташовані правіше. При цьому адреси в регістрах SI, DI і BX збільшуються на 2. Цю операцію виконують по дві команди INC для кожного регістра. Застосовувати команду ADD reg,02 у цьому випадку не можна, тому що при цьому буде очищений прапорець переносу, що приведе до спотворення результату додавання. Оскільки використовується цикл, виконується лише команда додавання ADC. Перед циклом команда CLC (CLear Carry - очистити прапор переносу) установлює нульове значення прапорця переносу. Для віднімання багатобайтних чисел слід використовувати команду SBB (віднімання з запозиченням), яка є еквівалентом ADD.
Множення
Операція множення для беззнакових даних виконується командою MUL, а для знакових - IMUL (Integer MULtiplication - множення цілих чисел). У єдиному операнді команд MUL і IMUL вказується множник. Відповідальність за контроль над форматом чисел, що обробляються і за вибір відповідної команди множення лежить на самому програмісті. Існують дві основні операції множення:
"Байт на байт". Множене перебуває в регістрі AL, а множник у байті пам'яті або в однобайтовом регістрі. Після множення добуток перебуває в регістрі AX. Операція ігнорує і витирає будь-які дані, які були в регістрі AH.
AX=AL*регістр8/пам’ять8
"Слово на слово". Множене перебуває в регістрі AX, а множник - у слові пам'яті або у двобайтному регістрі. Після множення добуток знаходиться в подвійному слові, для якого потрібно два регістри: старша (ліва) частина добутку - в регістрі DX, а молодша (права) частина - в регістрі AX. Операція ігнорує й стирає будь-які дані, які перебували в регістрі DX.
DX:AX=AX* регістр16/пам’ять16
Ділення.
Операція ділення для беззнакових даних виконується командою DIV, a для знакових - IDIV. Відповідальність за вибір відповідної команди лежить на програмісті. Існують дві основні операції ділення:
"Слово на байт". Ділене перебуває в регістрі AX, а дільник - у байті пам'яті або а однобайтовому регістрі. Після ділення остача виходить у регістрі AH, а частка - в AL. Оскільки однобайтова частка дуже мала (максимально +255 (.FFh) для беззнакового ділення і +127 (7Fh) для знакового), то дана операція має обмежене використання.
AX / регістр8 = AL(частка) AH(остача)
AX / пам’ять8 = AL(частка) AH(остача)
"Подвійне слова на слово". Ділене перебуває в регістровій парі DX:AX, а дільник - у слові пам'яті або в регістрі. Після ділення остача виходить у регістрі DX, а частка в регістрі AX. Частка в одному слові допускає максимальне значення +32767 (FFFFh) для беззнакового ділення і +16383 (7FFFh) для знакового.
DX(старша частина) AX(молодша частина) / регістр16 = AX(частка) DX(остача)
DX(старша частина) AX(молодша частина) / пам’ять16 = AX(частка) DX(остача)
У єдиному операнді команд DIV і IDIV вказується дільник. Команда IDIV (Integer DIVide) виконує ділення знакових чисел. Таким чином, якщо ділене й дільник мають однаковий знаковий біт, то команди DIV і IDIV генерують однаковий резуультат . Але, якщо ділене й дільник мають різні знакові біти, то команда DIV генерує додатну частку, а команда IDIV – від’ємну частку.
Виконання:
Завдання:
Створити *.exe програму, яка реалізовує обчислення, заданого варіантом виразу і зберігає результат в пам’яті.Вхідні операнди А, В, С, D, E, F вважати беззнаковими і довжиною в байтах, згідно з індексу; К – константа, довжина якої визначається значенням(згідно варіанту). Для її опису слід використати директиву EQU.
За допомогою Debug, відслідкувати правильність виконання програми (продемонструвати результати проміжних та кінцевих обчислень).
23
X=A2*B2-C1+D4/E2+K
7AA02023
Рис.1 Вмістиме дампу пам’яті
/
Лістинг програми
DOSSEG
.MODEL SMALL
.STACK 100h
.DATA
K_Ml EQU 2023h
K_St EQU 7AA0h
A dw 7012h
B dw 1412h
C db 12h
D dd 38A221B8h
E dw 7878h
Temp1 dw 00h,00h
Temp2 dw 00h,00h
Temp3 dw 00h,00h
X dw 00h,00h,00h
.CODE
start:
mov ax,@data
mov ds,ax
mov ax,A
mul B
mov [Temp1+0], ax
mov [Temp1+2], dx
mov ax,word ptr[Temp1]
mov bh,00
mov bl,C
sub ax,bx
sbb word ptr[Temp1+2],0
mov word ptr[Temp3+0],ax
mov word ptr[Temp3+2],dx
mov ax,word ptr[D]
mov dx,word ptr[D+2]
div E
mov dx,K_St
add ax, K_Ml
mov [Temp2+0],ax
adc dx,0
mov [Temp2+2],dx
mov ax,word ptr[Temp3+0]
mov dx,word ptr[Temp2+0]
add ax,dx
mov [X],ax
adc [X+2],0
mov ax,word ptr[Temp3+2]
mov dx,word ptr[Temp2+2]
add ax,dx
mov [X+2],ax
adc [X+4],0
mov ah,4Ch
int 21h
end start
end