Міністерство освіти і науки України
Національний технічний університет України
«Київський політехнічний інститут імені Ігоря Сікорського»
Теплоенергетичний факультет
Кафедра автоматизації проектування енергетичних процесів і систем
Звіт
до лабораторної роботи №6
з дисципліни «Операційні системи»
Тема «Система команд. Арифметичні команди. Обчислення цілочисельних арифметичних виразів з використанням команд MUL, IMUL, DIV, IDIV, ADD, ADC, INC, SUB, SBB, DEC, NEG, CBW, CWD»
Варіант 12
КИЇВ-2022
Мета роботи : програмування блоку обчислення арифметичних виразів на прикладі реалізації математичних формул з використанням арифметичних команд асемблера за індивідуальними завданнями.
Короткий теоретичний опис
Команди переміщення даних
MOVe operand Пересилання операнда. MOVe operand to/from system registers Пересилання операнда у системні регістри (або з них). Схема команди: MOV приймальник, джерело. Призначення: пересилання даних між регістрами або регістрами та пам’яттю. Команда має обмеження:
копіювання здійснюється з другого операнда у перший;
значення другого операнда не змінююється;
обидва оператора не можуть бути з пам’яті;
лише один з операндів може бути сегментним, приймальником не може бути регістр CS; не можна пересилати сегментні регістри:
не можна напряму ініціалізувати сегмент даних
довжина обох операндів повинна бути однаковою.
Команда Mov має розширену можливість: для випадку, коли довжина операндів різна використовується директива заначення типу: Тип PTR вираз.
Оператор PTR може використовуватися з елементами даних, мітками інструкцій. Він використовує специфікатори типів Byte, Word, Dword, Tbyte для явного зазначення типу DB, DW, DD, DQ, DT для змінних. Він також використовує специфікатори типів NEAR, FAR, PROC для явного зазначення відстані до мітки переходу.
Арифметичні команди
Команда складання ADD (ADDition). Синтаксис: ADD приймальник, джерело. Символьний код: ADD регістр/пам’ять, регістр/пам’ять/безпосереднє значення.Призначення: складання двох операндів джерела та приймальника розмірністю байт, слово або подвійне слово, записати результат складання за адресою першого операнда, встановити прапорці. Ця операція є коректною при використанні операндів: регістр-регістр, регістр-пам’ять, пам’ять-пам’ять, пам’ять-безпосереднє значення.Виконання команди додавання впливає на стан прапорців: CF (Carry)– перенесення (зі старшого знакового розряду; наприклад, для байта в 9-му розряді при виконанні команди додавання з’явилася 1), PF (Parity)– парність, AF (Auxiliary)- допоміжне перенесення, ZF (Zero)– нуль, SF (Sign)– мінус, OF (Overflow)– переповнювання.
Команда ADD використовується для складання двох цілочисельних операндів. Якщо результат складання виходить за межі першого операнда (виникає переповнювання), то врахувати цю ситуацію слід шляхом аналізу прапорця CF і подальшого можливого застосування команди ADC.
Команда складання двох операндів з урахуванням перенесенням з молодшого розряда ADC (ADDition with Carry).Синтаксис: ADС приймальник, джерело. Символьний код: ADС регістр/пам’ять, регістр/пам’ять/безпосереднє значення. Впливає на прапорці AF, CF, OF, PF, SF, ZF Результат заноситься у перший операнд, в залежності від результату встановлюються прапорці. Логіка роботи команди: <приймальник>=<приймальник>+<джерело>+<CF>.
Команда ADC використовується при складанні багаторозряднихдвійкових чисел. Її можна використовувати як самостійно, так і спільно з командою ADD. При спільному використанні команди ADC з командою ADD складання молодших байтів/слів/подвойних слів здійснюється командою ADD, а вже старші байти/слова/подвойні слова складаються командою ADC, що враховує перенесення з молодших розрядів в старші. Тобто команда ADC додає вміст прапорця перенесення CF (0 або 1) до першого операнда - приймальника, а потім додає до приймальника другий операнд – джерело.
Команда віднімання SUB (SUBtract). Синтаксис: SUB операнд_1, операнд_2. Символьний код: SUB регістр/пам’ять, регістр/пам’ять/безпосереднє значення. Впливає на прапорці AF, CF, OF, PF, SF, ZF. Команда призначена для віднімання цілочисельних операндів або для віднімання молодших частин значень багатобайтних операндів. Віднімання здійснюється за методом складання з двійковим доповненням: для другого операнда встановлюється додатковий код (біти
інвертуються +1), а потім відбувається складання з першим операндом. Операнд_2 віднімається від операнда_1, результат записується в операнд_1. Команда SUB діє як приймальник = приймальник – джерело. Виконання команди віднімання впливає на стан прапорців: CF – перенесення (зі старшого знакового розряду; наприклад, для байта в 9-му розряді при виконанні команди додавання з’явилася 1), PF – парність, AF- допоміжне перенесення, ZF – нуль, SF – мінус, OF – переповнювання. При відніманні прапорець CF діє як ознака зайняття.
Команда віднімання із зайняттям (заемом) SBB (SuBtract with Borrow) або віднімання з перенесенням. Синтаксис: SBB операнд_1, операнд_2. Символьний код: SBB регістр/пам’ять, регістр/пам’ять/безпосереднє значення. Команда призначена для виконання цілочисельного віднімання старших частин значень багатобайтних операндів з урахуванням можливого попереднього зайняття при відніманні молодших частин значень цих операндів, коли виконувалося попереднє віднімання командами SBB та SUB (за станом прапорця перенесення CF). Команда SBB спочатку віднімає вміст прапорця CF з операнда_1 та віднімає з операнда_1 операнд_2: приймальник = приймальник - джерело -перенесення.
Команда множення двох цілих двійковихчисел без урахування знаку MUL (MULtiply). Команда перемножує два цілих числа без знаку. Синтаксис: MUL множник_1. Символьний код: MUL регістр/пам’ять. Команда MUL сприймає старший біт в якості біта даних , а не як біт знака. Алгоритм роботи команди залежить від формату операнда команди і вимагає явної вказівки місцеположення тільки одного співмножника, який може бути розташований в пам'яті або в регістрі (перший співмножник). Місцеположення другого співмножника фіксовано і залежить від розміру першого співмножника:
якщо операнд, вказаний в команді, — байт, то другий співмножник повинен розташовуватися в AL;
якщо операнд, вказаний в команді, — слово, то другий співмножник повинен розташовуватися в АХ;
якщо операнд, вказаний в команді, — подвійне слово, то другий співмножник повинен розташовуватися в EAX.
Результат множення поміщається також у фіксоване місце, яке визначається розміром співмножників:
при перемноженні байтів результат поміщається в АХ;
при перемноженні слів результат поміщається в пару DX:AX (молодші розряди - в AX, старші - в DX) і встанавлюються прапорці переповнення и перенесення;
при перемноженні подвійних слів результат поміщається в пару ЕDX:EAX (молодші розряди - в ЕAX, старші - в ЕDX) і встанавлюються прапорці переповнення и перенесення.
Контролювати розмір результату зручно, використовуючи прапорці CF або OF (прапорці AF, PF, SF, ZF –не визначено). Після виконання команди MUL прапорці CF і OF дорівнюються 0, якщо старша половина множення дорівнюється нулю; інакше обидва ці прапорці дорівнюються 1. Множення і ділення це одні з найповільніших операцій процесорів сімейства 80х86 (особливо 8086 і 8088). Множення і ділення на константи, що часто зустрічаються, швидше відбувається при зсуві розрядів.
Команда множення двох цілих двійкових чисел з урахуванням знаку IMUL (Integer MULtiply). Команда виконує цілочисельне множення операндів з урахуванням їх знакових розрядів. Команда сприймає старші(перші ліворуч) біти чисел в якості знаків (0 – позитивне число, 1 – негативне число). Для виконання цієї операції необхідно наявність двох співмножників. Розміщення і задання їх місцеположення в команді залежить від форми вживаної команди множення, яка, у свою чергу, визначається моделлю мікропроцесора. Так, для мікропроцесора i8086 можлива тільки однооперандна форма команди, для подальших моделей мікропроцесорів додатково можна використовувати двох- і трьохоперандні форми цієї команди. Синтаксис: ІMUL множник_1; ІMUL множник_1, множник_2; ІMUL результат, множник_1, множник_2. Символьний код: ІMUL регістр/пам’ять, ІMUL регістр, безпосереднє значення (для 80286 і вище), ІMUL регістр, регістр, безпосереднє значення (для 80286 і вище) ІMUL регістр, регістр/пам’ять (для 80386 та вище).
Команда беззнакового ділення DIV (DIVide unsigned). Команда призначена для ділення двох двійкових беззнакових чисел. Синтаксис: DIV дільник.Символьний код: DIV регістр/пам’ять.
Команда знакового цілочисельного ділення ІDIV (Integer DIV idesigned). Команда призначена для ділення двох двійкових чисел зі знаком, ділить знакове ділиме націло на знаковий дільник. Команда ІDIV сприймає в якості знака старші (перші ліворуч) біти (1- від’ємне число, 0 – позитивне число). Ділення на нуль викликає переривання. Синтаксис: ІDIV дільник. Символьний код: DIV регістр/пам’ять.
Завдання: (25/c-d+2)/(b+a^2-1) -Варіант 12.
Код програми
;Лабораторна робота № 6
;Виконала: Ткаченко Майя Вадимівна, ТР-15, 03.06.22
;Арифметичні команди
;Обчислити q=(25/c-d+2)(b+a^2-1)
.model small
.stack 100h
.data
a dw 2
b dw 3
c dw 5
d dw 1
q dw ? ; змінні для збереження результатів
m dw ? ; обчислень
task db "q = (25/c-d+2)/(b+a^2-1)$" ;формула
;за якою здійснюється обчислення
variables db "a = 2; b = 3; c = 5; d = 1$";змінні
res db "q : "
CR_LF db 0dh,0ah, "$"
msg db 'Error! Devision by zero.$';повідомлення про помилку
.code
pochatok:
mov ax,@data ;завантаження адреси сегменту даних в АХ
mov ds,ax ;завантаження вмісту АХ регістр сегменту даних
mov ah,09h ;виведення
mov dx, offset task;формули за якою
int 21h ;будуть проводитися обчислення
mov ah,09h
mov dx, offset CR_LF;перехід на новий рядок
int 21h
mov ah,09h
mov dx, offset variables ;вивдення ініціалізованих змінних
int 21h
mov ah,09h
mov dx, offset CR_LF
int 21h
mov ah,09h
mov dx, offset res
int 21h
;<<<Обчислення знаменника
mov ax, a
cwd
imul a
add ax, b
cmp ax, 1
je @err
sbb ax, 1
mov m, ax
;<<<Обчислення чисельника
cmp c, 0
je @err
mov ax, 25
cwd
idiv c
sbb ax, d
add ax, 2
cwd
idiv m
;присвоєння отриманого значення q
mov q,ax
xor ax,ax ;обнуляємо регістр АХ
mov ax,q
push ax
cmp ax, 0
jns @plus ; перевірка знаку числа
mov dl, '-';якщо число від'ємне виводимо '-'
mov ah, 02h
int 21h
pop ax
neg ax
@plus:
xor cx, cx ; лічильник остач
mov bx,10 ;завантаження 10-ї системи
@dvsn: ;обчислення остачі
xor dx,dx
div bx
push dx
inc cx
test ax,ax ; перевірка, чи рівна ціла частина 0
jnz short @dvsn
mov ah,02h ;виведення остачі
@vivod:
pop dx
add dl, 30h
int 21h
loop @vivod ;повторення до моменту поки СХ не дорівнюватиме 0
jmp @end
;<<<Повідомлення про помилку
@err:
mov dx, offset msg
mov ah, 09h
int 21h
;<<<Завершення програми
@end:
mov ax,4c00h
int 21h
end pochatok
Створення файлу з розширенням EXE
/
Робота з TD
Виконаємо покрокове виконання – F8 і проаналізуємо поведінку прапорців. Ось декілька скріншотів під час покрокового виконання.
/
Зазнав змін прапорець парності, встановлюється в 1, якщо молодший байт результату попередньої команди містить парне число бітів рівних 1.
/
Встановлюється в 0, якщо число одиничних біт непарне.
/
Білим підсвічено прапорець нуля, його значення тепер рівне одиниці, це означає, що результат попередньої команди ріний нулю.
Під час покрокового проходу інші прапорці не зазнавали змін, а отже не були застосовані.
Результати покрокового виконання програми.
/
Результати роботи з TD після переходу в консольний режим.
/
Висновок
Під час виконання даної лабораторної роботи освоєно арифметичні команди, обчислення цілочисельних арифметичних виразів з використанням команд MUL, IMUL, DIV, IDIV, ADD, ADC, INC, SUB, SBB, DEC, NEG, CBW, CWD.
Написано програму, яка обчислює вираз згідно свого варінату, також, для більшої наглядності, прорама виводить формулу обчислення і значення змінних. Проведено аналіз поведінки прапорців під час покрокового виконання в TD.