- •Методичесике указания к выполнению лабораторных работ по дисциплине
- •График проведения
- •Лабораторная работа № 1
- •Общие сведения
- •Задание
- •Содержание отчета
- •Что нужно знать для защиты отчета
- •Рекомендуемая литература
- •Лабораторная работа № 2
- •Общие сведения
- •Задание
- •Содержание отчета
- •Задание
- •Содержание отчета
- •Задание
- •Содержание отчета
- •Что нужно знать для защиты отчета
- •Рекомендуемая литература
- •Лабораторная работа № 5
- •Общие сведения
- •Задание
- •Варианты заданий
- •Содержание отчета
- •Задание
- •Варианты заданий
- •Содержание отчета
- •Что нужно знать для защиты отчета
- •Рекомендуемая литература
- •Лабораторная работа № 7
- •Общие сведения
- •Варианты заданий
- •Содержание отчета
- •Что нужно знать для защиты отчета
- •Рекомендуемая литература
Общие сведения
В группу команд двоичной целочисленной арифметики входят следующие команды:
Add – сложение;
Adc – сложение с учетом предыдущего переноса;
Sub – вычитание;
Sbb – вычитание с учетом предыдущего займа;
Mul – умножение данных без знака (т.е. все биты операндов рассматриваются командой как биты данных);
Imul – умножение знаковых данных (т.е. старший бит операндов рассматривается командой как знаковый бит);
Div – деление данных без знака;
Idiv – деление знаковых данных;
Inc – увеличение операнда на единицу;
Dec – уменьшение операнда на единицу;
Cbw – преобразование байта в слово;
Cwd – преобразование слова в двойное слово;
Cmp – cравнение операндов;
Neg – изменение знака операнда.
Задание
Внимательно изучить работу команд двоичной целочисленной арифметики по конспекту и электронной документации.
Написать на ассемблере программу, реализующую вычисление значения выражения, приведенного в таблице заданий, в соответствии с вариантом (номер по списку в журнале группы). Исходные данные инициировать в сегменте данных. Для промежуточных значений и результата в сегменте данных продекларировать области памяти необходимой длины, в зависимости от размера этих значений. В процессе выпол нения программы сохранять все промежуточные значения и результат в сегменте данных. Причем, сделаем ударение на том, что для каждого значения исходных данных, промежуточных значений и окончательного результата вычислений необходимо выделять свои области памяти (в одном сегменте данных), чтобы значения одних данных не затирались другими.
Программу выполнить по шагам в TD, анализируя состояние используемых регистров после выполнения каждой команды, области памяти, в которую записываются результаты вычислений и состояние флагового регистра.
Варианты заданий
№ варианта |
Выражение |
1 |
( ( 253 + 255 ) / 127 – 9 ) * 397 |
2 |
144 / 2 + (( 39 – 12 ) * 14 )/ 3 |
3 |
62352 / 36 + ( 987 – 750 ) * ( - 94 ) |
4 |
( 4400+3100 ) – ( 6500-700 ) / ( -50 ) |
5 |
( 584 – 399 + 256 ) * 300 + 350 / 70 |
6 |
( 357 – 400 ) * ( -52 ) + ( 147 + 367 ) / 257 |
7 |
144 * ( - 39 ) + ( 728 + 172 ) / 300 |
8 |
( 75389 *24 + 150 ) / 9 |
9 |
( 290 – 350 ) / (- 10 ) – ( 896 / 448 ) * 4 + 156 |
10 |
( 924 – 148 ) / 97 + ( 250 * 397 ) * 248 |
11 |
( 584 – 256 ) * ( -7 ) + ( 218 + 679 ) / 299 |
12 |
( 1708 / 427 ) * ( - 5 ) + ( 357 – 400 ) * 352 |
13 |
280 / ( - 70 ) + ( 987 + 750 ) * 450 |
14 |
6358 / 2 + ( 350 – 700 ) * 59 |
15 |
( 728 + 156 ) / 442 + 150 * ( - 3 ) |
16 |
144 / 48 + ( 350 – 700 ) * 59 |
17 |
( 48 – 12 ) * 260 + ( 60 – 72 ) / ( - 4 ) |
18 |
850 * 39 + ( 170 – 18 ) / ( - 38 ) |
19 |
( 728 + 150 ) * 5 – 67500 / 450 |
20 |
( 880 + 970 ) / 50 – ( 875 / 125 ) * 7 |
21 |
( 359 – 120 ) * 25 – 192 / 64 + 1116 / 279 |
22 |
( 470+550 ) / ( 243+777 )+( 100-140 ) |
Продолжение таблицы вариантов заданий
23 |
( 13711 + 497 ) / ( - 128 ) + ( 540 / ( 257 – 149 )) * ( - 32 ) |
24 |
( 139 – 277 ) * ( -255 ) + 688 / ( 700 –528 ) |
25 |
45500 / 325 – ( 397 + 288 ) * ( -5 ) |
26 |
( 115 – 250 ) * ( -3 ) + 55199 / 289 |
27 |
362 + ( 125 – 55 ) / 35 + 308 / (( 25 – 14 ) * 2 ) |
28 |
243 / ( -27 ) + 55440 / 720 * ( 140 – 35 ) |
29 |
( 535 – 628 ) * 22 – 407 / ( - 37 ) |
30 |
257 * ( - 9 ) + ( 241 + 335 ) / 48 |
Пример программы работы с командами двоичной арифметики
Задание: ( 590-770 ) * 54 + 950 / ( 75+20 )
Для удобства дальнейшего анализа работы программы составим таблицы соответствия данных их шестнадцатеричным значениям.
Исходные данные |
Их шестнадцатеричный эквивалент |
| |
590 |
2 4E h |
| |
770 |
3 02 h |
| |
54 |
36 h |
| |
75 |
48 h |
| |
20 |
14 h |
| |
950 |
3 B6 h |
| |
Промежуточные результаты |
Их шестнадцатеричный эквивалент | ||
( 590 – 770 ) = -180 |
FF 4C h | ||
( 590 – 770 ) * 54 = - 9720 |
FFFF DA08 h | ||
( 75 + 20 ) = 95 |
37 h | ||
950 / ( 75 + 20 ) = 10 |
A h |
Результат вычислений |
Его шестнадцатеричный эквивалент |
( 590-770 ) * 54 + 950 / ( 75+20 )
|
FFFF DA12 h |
Data SEGMENT
IsB DB 54,75,20
IsW DW 590,770,950
PromRezB DB 2 dup (0)
PromRezW DW 5 dup (0)
Data ENDS
Code SEGMENT
ASSUME DS:Data,CS:Code,SS:Stack1,ES:Data
Start: ; Настройка регистра DS на начало сегмента данных нашей программы
mov AX,Data
mov DS,AX
;Вычисление значения (590-770)
mov AX,IsW ; загрузка на регистр AX значения 590
sub AX,isW+2 ;вычитание из AX значения 770.
;Результат будет на AX
mov PromRezW,AX ; запись результата вычитания в область
;памяти для промежуточных результатов
; Вычисление значения (590-770)*54
;Умножение в данной ситуации должно быть знаковым
;(т.е. выполнять его будем командой IMUL),
;так как результат выполнения действия вычитания - отрицательное значение.
;Кроме того, мы должны учесть, что в данном умножении у нас ;участвуют
;одно байтовое значение (54) и одно слово (-180),
;но так как команда умножения выполняет обработку данных
;только по схемам:
;AL * байт -> результат на AX или
;AX * слово -> результат на регистровой паре DX:AX,
;то мы должны байтовое значение (54) использовать как словесное,
;для этого 54 мы запишем на BL (младший байт регистра BX)
;а старший байт регистра BX - BH - обнулим при помощи команды xor.
;Значение результата вычитания у нас уже находиться на AX
;после последнего действия
mov BL,IsB ;загрузка на BL значения 54
xor BH,BH ;обнуление старшего байта регистра BH
imul BX ;результат умножения будет на регистровой паре DX:AX
;сохранение в сегменте данных младшей части результата
mov PromRezW+2,AX
;сохранение в сегменте данных старшей части результата
mov PromRezW+4,DX
;Вычисление значения (75+20)
mov BL,IsB+1 ;запись на BL исходного значения 75
add BL,IsB+2 ;суммирование его с исходным значением 20
mov PromRezB,BL ;сохранение результата в сегменте
; данных
;Выполнение действия (950/(75+20))
;Так как и делимое и делитель числа положительные,
;то для деления выбираем команду целочисленного без знакового деления DIV
;Деление на ассемблере выполняется по следующим схемам:
;AX/байт -> результат распределяется так:
;в AL - частное, в AH - остаток
;или DX:AX/слово -> результат распределяется так:
;в AX - частное, в DX - остаток.
;Так как в нашей ситуации длина делимого (950) слово, а делителя байт (95),
;то у нас будет первый вариант схемы выполнения деления
;Загружаем на AX делимое
mov AX,IsW+4
;делитель в данный момент у нас уже на регистре BL
;после выполнения действия сложения (вычисление значения знаменателя)
;Делим
div BL
;Сохраняем частное в сегменте данных
mov PromRezB,AL
;Остаток - равен нулю
;Вычисление результата = (590-770)*54 + 950/(75+20)
;Суммирование промежуточных результатов вычисления двух частей выражения
;Так как мы должны просуммировать значение двухсловное с байтовым,
;суммирование будем выполнять так: младшее слово с байтом,
;приведенным к длине слова
mov CX,PromRezW+2 ;загрузка на CX первого слагаемого
xor AH,AH ;обнуление старшего байта AX
;(там сейчас находится остаток от деления)
add CX,AX ;суммируем, результат будет на CX
mov PromRezW+6,CX
;переписываем старшую часть результата
;(она сейчас в ячейке памяти по адресу PromRez+4
;и на регистре DX, так как после умножения мы этот регистр не использовали)
mov PromRezW+8,DX
;Завершаем программу
mov ah,4ch
int 21h
code SEGMENT
stack1 segment 'stack'
DB 80 dup (0)
stack1 ends
end start