Міністерство освіти і науки УкраїниНаціональний технічний університет України
«Київський політехнічний інститут ім. І. Сікорського»
Кафедра автоматизації проектування енергетичних процесів і систем
Лабораторна робота №6
з дисципліни «Операційні системи»
«Система команд. Арифметичні команди. Обчислення цілочисельних
арифметичних виразів з використанням команд MUL, IMUL, DIV, IDIV,
ADD, ADC, INC, SUB, SBB, DEC, NEG, CBW, CWD»
КИЇВ-2022
Лабораторна робота №6
Мета роботи: програмування блоку обчислення арифметичних виразів на прикладі реалізації математичних формул з використанням арифметичних команд асемблера за індивідуальними завданнями.
Теоретична частина
6.1.1 MOVe operand - пересилання операнда. MOVe operand to/from system registers - пересилання операнда у системні регістри (або з них)
Схема команди: MOV приймальник, джерело
Призначення: пересилання даних між регістрами або регістрами та пам’яттю. Команда має обмеження:
копіювання здійснюється з другого операнда у перший;
значення другого операнда не змінюється;
обидва оператора не можуть бути з пам’яті;
лише один з операндів може бути сегментним, приймальником не може бути регістр CS; не можна пересилати сегментні регістри:
MOV ES, DS
Треба розписати:
MOV AX, DS
MOV ES, AX
не можна напряму ініціалізувати сегмент даних
DSEG SEGMENT
………………………
MOV DS, DSEG
Треба розписати:
MOV AX, DSEG
MOV DS, AX
довжина обох операндів повинна бути однаковою.
Команда Mov має розширену можливість: для випадку, коли довжина операндів різна використовується директива значення типу:
Тип PTR вираз
Оператор PTR може використовуватися з елементами даних, мітками інструкцій. Він використовує специфікатори типів Byte, Word, Dword, Tbyte для явного зазначення типу DB, DW, DD, DQ, DT для змінних. Він також використовує специфікатори типів NEAR, FAR, PROC для явного зазначення відстані до мітки переходу. Таким чином, тип – це специфікатор типу, наприклад, BYTE, а вираз – це змінна або константа.
6.2 Арифметичні команди
6.2.1 Команда складання ADD (ADDition)
Синтаксис: ADD приймальник, джерело
Символьний код: ADD регістр/пам’ять, регістр/пам’ять/безпосереднє значення
Призначення: складання двох операндів джерела та приймальника розмірністю байт, слово або подвійне слово, записати результат складання за адресою першого операнда, встановити прапорці.
Ця операція є коректною при використанні операндів: регістр-регістр, регістр-пам’ять, пам’ять-пам’ять, пам’ять-безпосереднє значення.
Виконання команди додавання впливає на стан прапорців:
CF (Carry) – перенесення (зі старшого знакового розряду), PF (Parity) – парність, AF (Auxiliary) – допоміжне перенесення, ZF (Zero) – нуль, SF (Sign) – мінус, OF (Overflow) – переповнювання.
Команда ADD використовується для складання двох цілочисельних операндів. Якщо результат складання виходить за межі першого операнда (виникає переповнювання), то врахувати цю ситуацію слід шляхом аналізу прапорця CF і подальшого можливого застосування команди ADC. При складанні слід врахувати можливість переповнювання.
6.2.2 Команда складання двох операндів з урахуванням перенесенням з молодшого розряда ADC (ADDition with Carry)
Синтаксис: ADС приймальник, джерело.
Символьний код: ADС регістр/пам’ять, регістр/пам’ять/безпосереднє значення
Впливає на прапорці AF, CF, OF, PF, SF, ZF
Результат заноситься у перший операнд, в залежності від результату встановлюються прапорці.
Логіка роботи команди: <приймальник>=<приймальник>+<джерело>+<CF>
Команда ADC використовується при складанні багаторозрядних двійкових чисел. Її можна використовувати як самостійно, так і спільно з командою ADD. При спільному використанні команди ADC з командою ADD складання молодших байтів/слів/подвойних слів здійснюється командою ADD, а вже старші байти/слова/подвойні слова складаються командою ADC, що враховує перенесення з молодших розрядів в старші.
6.2.3 Команда віднімання SUB (SUBtract)
Синтаксис: SUB операнд_1, операнд_2
Символьний код: SUB регістр/пам’ять, регістр/пам’ять/безпосереднє значення
Впливає на прапорці AF, CF, OF, PF, SF, ZF
Команда призначена для віднімання цілочисельних операндів або для віднімання молодших частин значень багатобайтних операндів. Віднімання здійснюється за методом складання з двійковим доповненням: для другого операнда встановлюється додатковий код (біти інвертуються +1), а потім відбувається складання з першим операндом. Операнд_2 віднімається від операнда_1, результат записується в операнд_1.
Команда SUB діє як приймальник = приймальник – джерело
Виконання команди віднімання впливає на стан прапорців:
CF – перенесення (зі старшого знакового розряду), PF – парність, AF - допоміжне перенесення, ZF – нуль, SF – мінус, OF – переповнювання. При відніманні прапорець CF діє як ознака зайняття.
6.2.4 Команда віднімання із зайняттям SBB (SuBtract with Borrow) або віднімання з перенесенням
Синтаксис: SBB операнд_1, операнд_2
Символьний код: SBB регістр/пам’ять, регістр/пам’ять/безпосереднє значення
Команда призначена для виконання цілочисельного віднімання старших частин значень багатобайтних операндів з урахуванням можливого попереднього зайняття при відніманні молодших частин значень цих операндів, коли виконувалося попереднє віднімання командами SBB та SUB (за станом прапорця перенесення CF).
Команда SBB спочатку віднімає вміст прапорця CF з операнда_1 та віднімає з операнда_1 операнд_2: приймальник = приймальник - джерело - перенесення.
6.2.5 Команда множення двох цілих двійковихчисел без урахування знаку MUL (MULtiply)
Команда перемножує два цілих числа без знаку.
Синтаксис: MUL множник_1
Символьний код: MUL регістр/пам’ять.
Команда MUL сприймає старший біт в якості біта даних , а не як біт знака. Алгоритм роботи команди залежить від формату операнда команди і вимагає явної вказівки місцеположення тільки одного співмножника, який може бути розташований в пам'яті або в регістрі (перший співмножник). Місцеположення другого співмножника фіксовано і залежить від розміру першого співмножника:
якщо операнд, вказаний в команді, — байт, то другий співмножник повинен розташовуватися в AL;
якщо операнд, вказаний в команді, — слово, то другий співмножник повинен розташовуватися в АХ;
якщо операнд, вказаний в команді, — подвійне слово, то другий співмножник повинен розташовуватися в EAX.
Результат множення поміщається також у фіксоване місце, яке визначається розміром співмножників:
при перемноженні байтів результат поміщається в АХ;
при перемноженні слів результат поміщається в пару DX:AX (молодші розряди - в AX, старші - в DX) і встановлюються прапорці переповнення и перенесення;
при перемноженні подвійних слів результат поміщається в пару ЕDX:EAX (молодші розряди - в ЕAX, старші - в ЕDX) і встановлюються прапорці переповнення и перенесення;
Контролювати розмір результату зручно, використовуючи прапорці CF або OF (прапорці AF, PF, SF, ZF –не визначено).
6.2.6 Команда множення двох цілих двійкових чисел з урахуванням знаку IMUL (Integer MULtiply)
Команда виконує цілочисельне множення операндів з урахуванням їх знакових розрядів. Команда сприймає старші (перші ліворуч) біти чисел в якості знаків (0 – позитивне число, 1 – негативне число). Для виконання цієї операції необхідно наявність двох співмножників. Розміщення і задання їх місцеположення в команді залежить від форми вживаної команди множення, яка, у свою чергу, визначається моделлю мікропроцесора.
Синтаксис: ІMUL множник_1
ІMUL множник_1, множник_2
ІMUL результат, множник_1, множник_2
Символьний код: ІMUL регістр/пам’ять
ІMUL регістр, безпосереднє значення (для 80286 і вище)
ІMUL регістр, регістр, безпосереднє значення (для 80286 і вище)
ІMUL регістр, регістр/пам’ять (для 80386 та вище)
Команда imul встановлює в нуль прапорці OF і CF, якщо розмір результату відповідає регістру призначення. Інші прапорці AF, PF, SF, ZF є невизначеними.
6.2.7 Команда беззнакового ділення DIV (DIVide unsigned) Команда призначена для ділення двох двійкових беззнакових чисел.
Синтаксис: DIV дільник
Символьний код: DIV регістр/пам’ять
Алгоритм роботи: для команди необхідно задати два операнди — ділимого і дільника, беззнакове ділиме ділить націло дільник. Ділиме задається неявно і розмір його залежить від розміру дільника, який вказується в команді:
якщо дільник розміром в байт, то ділиме повинно бути розташовано в регістрі АХ. Після операції частка поміщається в AL, а залишок — в AH;
якщо дільник розміром в слово, то ділиме повинно бути розташовано в парі регістрів DX:AX, причому молодша частина ділимого знаходиться в АХ. Після операції частка поміщається в АХ, а залишок — в DX;
якщо дільник розміром в подвійне слово, то ділиме повинно бути розташовано в парі регістрів EDX:EAX, причому молодша частина ділимого знаходиться в EAX. Після операції частка поміщається в EAX, а залишок — в EDX.
Ділення на нуль викликає переривання.
6.2.8 Команда знакового цілочисельного ділення ІDIV (Integer DIVide signed)
Команда призначена для ділення двох двійкових чисел зі знаком, ділить знакове ділиме націло на знаковий дільник. Ділення на нуль викликає переривання.
Синтаксис: ІDIV дільник
Символьний код: DIV регістр/пам’ять
Алгоритм роботи: для команди необхідно задати два операнди — ділиме і дільник. Ділиме задається неявно, і розмір його залежить від розміру дільника, місцезнаходження якого вказується в команді:
якщо дільник розміром в байт, то ділиме повинно бути розташовано в регістрі АХ. Після операції частка поміщається в AL, а залишок — в AH;
якщо дільник розміром в слово, то ділиме повинно бути розташовано в парі регістрів DX:AX, причому молодша частина ділимого знаходиться в ах. Після операції частка поміщається в АХ, а залишок — в DX;
якщо дільник розміром в подвійне слово, то ділиме повинно бути розташовано в парі регістрів EDX:EAX, причому молодша частина ділимого знаходиться в eax. Після операції частка поміщається в EAX, а залишок — в EDX;
Залишок завжди має знак ділимого. Знак частки залежить від стану знакових бітів (старших розрядів) ділимого і дільника.
Впливає на стан прапорців AF, CF, OF, PF, SF, ZF.
Завдання
Підготуйте і налагодьте програму для обчислення простих формул за зразком. Продемонструйте роботу програми під керуванням налагоджувача, прокоментуйте вміст обчислюваних змінних.
Індивідуальне завдання (варіант 11): (2*c – d*42)/(c + a – 1)
Код програми:
; Лабораторна робота 6 "Системне програмування"
; Тимкова А.В., ТР-15, 12.05.2022
; Арифметичні команди
; Обчислення формули: (2*c-d*42)/(c+a-1)
.MODEL small
.Stack 100h ; сегмент стеку
.data ; сегмент даних
a dw 2 ; змінна а
d dw -1 ; змінна b
c dw 3 ; змінна c
k dw ? ; додаткова змінна k
h dw ? ; додаткова змінна h
g dw ? ; додаткова змінна g
z dw ? ; змінна для збереження результату
zm dw ? ; знаменник
mess db 'Error! Devide by zero.$' ; Повідомлення про помилку
.code ;сегмент коду
begin:
MOV ax, @data
mov ds,ax
;Знаменник (с+а-1)
mov ax, c
add ax, a
sub ax, 1
cmp ax, 0 ; Перевірка чи знаменник = 0
je @err ; Якщо так, то виведення повідомлення про помилку
mov zm, ax
;d*42
mov k,42
mov ax,d
imul k
mov k,ax
;2*c
mov h, 2
mov ax, c
imul h
;Чисельник (2*c - d*42)
sub ax, k
;(2*c - d*42)/(c + a - 1)
cwd
idiv zm
mov z, ax
xor ax, ax
mov ax, z
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
@dvsn: xor dx, dx
div bx
push dx
inc cx
test ax, ax
jnz short @dvsn
mov ah, 02h
@vivod: pop dx
add dl, 30h
int 21h
loop @vivod
jmp @end
@err: mov dx, offset mess
mov ah, 09h
int 21h
@end: mov ax, 4c00h
int 21h
end begin
Створення .ехе файлу
/
Робота програми в середовищі налагоджувача ТD:
/
Результат виконання програми:
/
Якщо ми замінимо значення змінних так, щоб знаменник дорівнював 0, то отримаємо такий результат:
.MODEL small
.Stack 100h ; сегмент стеку
.data ; сегмент даних
a dw 0 ; змінна а
d dw -1 ; змінна b
c dw 1 ; змінна c
k dw ? ; додаткова змінна k
h dw ? ; додаткова змінна h
/
Лістинг:
Turbo Assembler Version 3.1 05/12/22 16:54:57 Page 1
lab6.asm
1 ; Лабораторна робота 6 "Системне програмування"
2 ; Тимкова А.В., ТР-15, 12.05.2022
3 ; Арифметичні команди
4 ; Обчислення формули: (2*c-d*42)/(c+a-1)
5
6 0000 .MODEL small
7 0000 .Stack 100h ; сегмент стеку
8 0000 .data ; сегмент даних
9 0000 0002 a dw 2 ; змінна а
10 0002 FFFF d dw -1 ; змінна b
11 0004 0003 c dw 3 ; змінна c
12 0006 ???? k dw ? ; додаткова змінна k
13 0008 ???? h dw ? ; додаткова змінна h
14 000A ???? g dw ? ; додаткова змінна g
15 000C ???? z dw ? ; змінна для збереження результату
16 000E ???? zm dw ? ; знаменник
17 0010 45 72 72 6F 72 21 20+ mess db 'Error! Devide by zero.$' ; Повідомлення про помилку
18 44 65 76 69 64 65 20+
19 62 79 20 7A 65 72 6F+
20 2E 24
21
22 0027 .code ;сегмент коду
23 0000 begin:
24 0000 B8 0000s MOV ax, @data
25 0003 8E D8 mov ds,ax
26
27 ;Знаменник (с+а-1)
28 0005 A1 0004r mov ax, c
29 0008 03 06 0000r add ax, a
30 000C 2D 0001 sub ax, 1
31 000F 3D 0000 cmp ax, 0 ; Перевірка чи знаменник = 0
32 0012 74 5C je @err ; Якщо так, то виведення повідомлення про помилку
33 0014 A3 000Er mov zm, ax
34
35 ;d*42
36 0017 C7 06 0006r 002A mov k,42
37 001D A1 0002r mov ax,d
38 0020 F7 2E 0006r imul k
39 0024 A3 0006r mov k,ax
40
41 ;2*c
42 0027 C7 06 0008r 0002 mov h, 2
43 002D A1 0004r mov ax, c
44 0030 F7 2E 0008r imul h
45
46 ;Чисельник (2*c - d*42)
47 0034 2B 06 0006r sub ax, k
48
49 ;(2*c - d*42)/(c + a - 1)
50 0038 99 cwd
51 0039 F7 3E 000Er idiv zm
52 003D A3 000Cr mov z, ax
53
54 0040 33 C0 xor ax, ax
55 0042 A1 000Cr mov ax, z
56 0045 50 push ax
57 0046 3D 0000 cmp ax, 0
_Turbo Assembler Version 3.1 05/12/22 16:54:57 Page 2
lab6.asm
58 0049 79 09 jns @plus
59 004B B2 2D mov dl, '-'
60 004D B4 02 mov ah, 02h
61 004F CD 21 int 21h
62 0051 58 pop ax
63 0052 F7 D8 neg ax
64
65 0054 33 C9 @plus: xor cx, cx
66 0056 BB 000A mov bx, 10
67
68 0059 33 D2 @dvsn: xor dx, dx
69 005B F7 F3 div bx
70 005D 52 push dx
71 005E 41 inc cx
72 005F 85 C0 test ax, ax
73 0061 75 F6 jnz short @dvsn
74 0063 B4 02 mov ah, 02h
75
76 0065 5A @vivod: pop dx
77 0066 80 C2 30 add dl, 30h
78 0069 CD 21 int 21h
79 006B E2 F8 loop @vivod
80
81 006D EB 08 90 jmp @end
82
83 0070 BA 0010r @err: mov dx, offset mess
84 0073 B4 09 mov ah, 09h
85 0075 CD 21 int 21h
86
87 0077 B8 4C00 @end: mov ax, 4c00h
88 007A CD 21 int 21h
89 end begin
_Turbo Assembler Version 3.1 05/12/22 16:54:57 Page 3
Висновок: у ході лабораторної роботи було ознайомлено та освоєно систему команд та арифметичні команди. Застосували на практиці обчислення цілочисельних арифметичних виразів з використанням команд MUL, IMUL, DIV, IDIV, ADD, ADC, INC, SUB, SBB, DEC, NEG, CBW, CWD.