Методичка - Микропроцессоры микроЭВМ
.pdfЛАБОРАТОРНАЯ РАБОТА № 4
Работа со стеком
1. Цель работы
Исследование правил работы со стеком, изучение команд PUSH, POP, CALL, RET,
RST.
2. Задание на лабораторную работу
Модифицировать программу третьей лабораторной работы таким образом, чтобы поиск конца массива производился в подпрограмме.
Перед выполнением программы сохранить все регистры микропроцессора в стеке и восстановить их после выполнения программы в исходное состояние.
3. Краткие сведения из теории
Стек – участок памяти в ОЗУ, выделенный программистом, в котором данные или адреса сохраняются и из которого извлекаются посредством стековых операций. Стековые операции выполняются командами PUSH, POP, CALL, RET, RST. Программист определяет, какой участок памяти выделяется под стек, с помощью специального 16-битового регистра, который называется стековым указателем (международное обозначение – SP, русское обозначение – УС). При работе со стеком выполняется следующее правило: «Первым вошел в стек, последним вышел из стека».
При работе со стеком различают две операции: запоминание данных из регистровой пары (PUSH) или счетчика команд (CALL, RST) в стеке и извлечение данных из стека в регистровую пару (POP) или в счетчик команд (RET).
Последовательность действий при запоминании данных в стеке:
1.Старшие 8 битов данных сохраняются в адресе памяти на 1 меньше, чем содержимое стекового указателя.
2.Младшие 8 битов данных сохраняются в адресе памяти на 2 меньше, чем содержимое стекового указателя.
3.Стековый указатель автоматически декрементируется (уменьшается) на 2. Последовательность действий при извлечении данных из стека:
1.Младшие 8 битов данных извлекаются из адреса памяти, соответствующей содержимому стекового указателя.
2.Старшие 8 битов данных извлекаются из адреса памяти, соответствующей содержимому стекового указателя + 1.
3.Стековый указатель автоматически инкрементируется на 2.
Часто группу команд в программе необходимо повторять много раз. Иногда в таких случаях лучше применять подпрограммы.
Подпрограмма кодируется подобно любой другой группе операторов языка, и к ней обращаются по имени, которое является меткой первой команды подпрограммы. Программист обращается к подпрограмме путем записи ее имени в поле операнда команды CALL. Когда выполняется CALL, адрес следующей команды после CALL вводится в стек и выполнение программы продолжается с первой команды подпрограммы. Когда подпрограмма завершила свою работу, выполняется команда RETURN, которая вызывает пересылку адреса из стека в счетчик команд, и выполнение программы продолжается с команды, следующей за CALL. Таким образом, одну копию подпрограммы можно вызывать из ряда точек без ее дублирования.
21
Подпрограмма (листинг 1) M1 инкрементирует 16-битовое число, сохраняемое в двух последовательных ячейках памяти, а затем возвращается к команде, которая следует за оператором CALL. Адрес инкрементируемого числа предварительно засылается в Н- и L- регистры.
Когда выполняется первый вызов, адрес 8204Н вводится в стек, а управление передается по адресу 8400Н. Выполнение любого оператора RET в теле подпрограммы M1 вызывает чтение адреса из стека в счетчик команд, выполнение продолжается с адреса 8204Н (поскольку оператор CALL имеет длину 3 байта).
Затем выполняется второй вызов, адрес 8306H вводится в стек, и управление снова передается M1. Теперь любая команда RETURN вызовет продолжение выполнения с ад-
реса 8306H.
Обратите внимание, что M1 в процессе могла бы вызвать другую подпрограмму, вызывая ввод в стек другого адреса. Ограничением является только размер памяти, доступной для стека.
Заметим, что любая подпрограмма может помещать данные в стек для временного хранения, что не повлияет на последовательность вызовов и возвратов, если только эти данные извлекаются из стека до выполнения команды RETURN.
Подпрограмме часто требуются данные для выполнения своих операций. В самом простом случае эти данные могут помещаться в один или несколько регистров. Программа M1, например, получает адрес памяти, который ей необходим, в Н- и L- регистрах. Иногда более удобно и экономно, чтобы регистры загружались в самой подпрограмме. Одним из способов выполнения этого является помещение списка необходимых данных (списка параметров) в какой-нибудь участок памяти и передача адреса этого списка в подпрограмму через Н- и L- регистры. Также это можно сделать путем передачи в подпрограмму списка параметров, который представляет собой список адресов параметров, а не самих параметров. На конец списка параметров указывает число, младший байт которого равен FFH (предполагается, что сам параметр не может равняться FFH). Возможно много вариантов передачи параметров. Например, если необходимо, чтобы параметры находились по любому адресу, то вызывающая программа могла бы передать общее число параметров в качестве первого параметра. Подпрограмма загрузила бы этот первый параметр в регистр и использовала бы его в качестве счетчика для определения конца списка параметров.
Листинг 1. Пример использования подпрограммы
№ |
Адрес |
Код |
Мет- |
Мнемоника |
Примечание |
|
|
|
ка |
|
|
1 |
8200 |
E5 |
|
PUSH H |
Запись в стек регистровой пары HL |
2 |
8201 |
CD 06 82 |
|
CALL M1 |
Вызов подпрограммы по метке М1 |
3 |
8204 |
E1 |
|
POP H |
Извлечение из стека регистровой пары |
|
|
|
|
|
HL |
4 |
8205 |
E7 |
|
RST32 |
Завершение программы |
|
|
|
|
|
|
|
8300 |
21 00 81 |
|
LXI |
|
|
|
|
|
H,8100H |
|
|
8303 |
CD 06 82 |
|
CALL M1 |
Вызов подпрограммы по метке М1 |
|
8306 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
8400 |
34 |
M1: |
INR M |
M(HL)=M(HL)+1 |
5 |
8401 |
C0 |
|
RNZ |
Условный возврат из подпрограммы |
|
8402 |
23 |
|
INX H |
HL=HL+1 |
|
8403 |
34 |
|
INR M |
M(HL)=M(HL)+1 |
6 |
8404 |
C9 |
|
RET |
Возврат из подпрограммы |
22
Рассмотрим программу (листинг 1). Этот фрагмент программы иллюстрирует поведение указателя стека при выполнении команд, работающих со стеком. В первом столбце (№) заданы номера контрольных точек, указывающих на состояние стека и указателя стека до выполнения команды в соответствующей строке.
Начальное значение стека обозначено буквами АААА (табл. 17). Стрелкой (→) обозначено положение указателя стека в каждой фазе выполнения программы. Звездочкой
(*) обозначено состояние стека после выполнения команды RST32.
Таблица 17. Состояние стека при разных фазах программы
AAAA -4 |
|
|
→04 |
→04 |
|
|
|
AAAA -3 |
|
|
82 |
82 |
|
|
|
AAAA -2 |
|
→L |
L |
L |
→L |
|
→06 |
AAAA -1 |
|
H |
H |
H |
H |
|
82 |
AAAA |
→ |
|
|
|
|
→ |
|
УС |
1 |
2 |
5 |
6 |
3 |
4 |
* |
4. Задание к лабораторной работе
Составить, отладить и продемонстрировать программу в соответствии с вариантом. При написании программы учесть следующее:
–Указатель стека проинициализирован в УОУ встроенным программным обеспечением и не требует задания.
–Возврат из подпрограммы необходимо производить только при помощи команд группы RET. Переход из тела подпрограммы в тело основной программы при помощи команд группы JMP вызывает заполнение стека неиспользованными адресами возврата и в итоге нарушает работу программы.
5.Содержание отчета
Отчет должен содержать листинг программы и блок-схему программы.
6. Контрольные вопросы
6. 1. На что воздействуют биты условий?
6. 2. Как выполняется команда CALL (RST, PUSH, POP, RET).
23
ЛАБОРАТОРНАЯ РАБОТА № 5
Выполнение сложных арифметических действий
1. Цель работы
Исследование правил двоичной арифметики, двоично-десятичной арифметики, шестнадцатеричной арифметики, программ перевода чисел из одной системы счисления в другую.
2. Задание на лабораторную работу
Разработать программу в соответствии с заданием (табл. 18)
Таблица 18. Задания к лабораторной работе № 5
|
|
1-й операнд |
2-й операнд |
|||
№ |
Задание |
Раз- |
Система |
Раз- |
Система |
|
ряд- |
счисле- |
ряднос |
счисле- |
|||
|
|
|||||
|
|
ность |
ния |
ть |
ния |
|
1 |
Преобразовать |
4 |
10 |
- |
8 |
|
2 |
Преобразовать |
4 |
8 |
- |
10 |
|
3 |
Преобразовать |
4 |
10 |
- |
16 |
|
4 |
Преобразовать |
4 |
16 |
- |
10 |
|
5 |
Преобразовать |
4 |
16 |
- |
8 |
|
6 |
Преобразовать |
4 |
8 |
- |
16 |
|
7 |
Преобразовать |
2 |
10 |
- |
8 |
|
8 |
Преобразовать |
2 |
8 |
- |
10 |
|
9 |
Преобразовать |
2 |
10 |
- |
16 |
|
10 |
Преобразовать |
2 |
16 |
- |
10 |
|
11 |
Преобразовать |
2 |
16 |
- |
8 |
|
12 |
Преобразовать |
2 |
8 |
- |
16 |
|
13 |
Перемножить |
4 |
10 |
4 |
10 |
|
14 |
Перемножить |
4 |
8 |
4 |
8 |
|
15 |
Перемножить |
4 |
16 |
4 |
16 |
|
16 |
Перемножить |
4 |
10 |
4 |
8 |
|
17 |
Перемножить |
4 |
10 |
4 |
16 |
|
18 |
Перемножить |
4 |
16 |
4 |
8 |
|
19 |
Перемножить |
2 |
10 |
4 |
10 |
|
20 |
Перемножить |
2 |
8 |
4 |
8 |
|
21 |
Перемножить |
2 |
16 |
4 |
16 |
|
22 |
Перемножить |
2 |
10 |
4 |
8 |
|
23 |
Перемножить |
2 |
10 |
4 |
16 |
|
24 |
Перемножить |
2 |
16 |
4 |
8 |
|
25 |
Поделить |
4 |
10 |
4 |
10 |
|
26 |
Поделить |
4 |
8 |
4 |
8 |
|
27 |
Поделить |
4 |
16 |
4 |
16 |
|
28 |
Поделить |
4 |
10 |
4 |
8 |
|
29 |
Поделить |
4 |
10 |
4 |
16 |
|
30 |
Поделить |
4 |
16 |
4 |
10 |
|
31 |
Поделить |
4 |
16 |
4 |
8 |
24
|
|
1-й операнд |
2-й операнд |
|||
№ |
Задание |
Раз- |
Система |
Раз- |
Система |
|
ряд- |
счисле- |
ряднос |
счисле- |
|||
|
|
|||||
|
|
ность |
ния |
ть |
ния |
|
32 |
Поделить |
4 |
8 |
4 |
10 |
|
33 |
Поделить |
4 |
8 |
4 |
16 |
|
34 |
Поделить |
2 |
10 |
4 |
10 |
|
35 |
Поделить |
2 |
8 |
4 |
8 |
|
36 |
Поделить |
2 |
16 |
4 |
16 |
|
37 |
Поделить |
2 |
10 |
4 |
8 |
|
38 |
Поделить |
2 |
10 |
4 |
16 |
|
39 |
Поделить |
2 |
16 |
4 |
10 |
|
40 |
Поделить |
2 |
16 |
4 |
8 |
|
41 |
Поделить |
2 |
8 |
4 |
10 |
|
42 |
Поделить |
2 |
8 |
4 |
16 |
|
43 |
Сложить |
4 |
10 |
4 |
10 |
|
44 |
Сложить |
4 |
8 |
4 |
8 |
|
45 |
Сложить |
4 |
16 |
4 |
16 |
|
46 |
Сложить |
4 |
10 |
4 |
8 |
|
47 |
Сложить |
4 |
10 |
4 |
16 |
|
48 |
Сложить |
4 |
16 |
4 |
8 |
|
49 |
Сложить |
6 |
10 |
6 |
10 |
|
50 |
Сложить |
6 |
8 |
6 |
8 |
|
51 |
Сложить |
6 |
16 |
6 |
16 |
|
52 |
Сложить |
6 |
10 |
6 |
8 |
|
53 |
Сложить |
6 |
10 |
6 |
16 |
|
54 |
Сложить |
6 |
16 |
6 |
8 |
|
55 |
Вычесть |
4 |
10 |
4 |
10 |
|
56 |
Вычесть |
4 |
8 |
4 |
8 |
|
57 |
Вычесть |
4 |
16 |
4 |
16 |
|
58 |
Вычесть |
4 |
10 |
4 |
8 |
|
59 |
Вычесть |
4 |
10 |
4 |
16 |
|
50 |
Вычесть |
4 |
16 |
4 |
10 |
|
61 |
Вычесть |
4 |
16 |
4 |
8 |
|
62 |
Вычесть |
4 |
8 |
4 |
10 |
|
63 |
Вычесть |
4 |
8 |
4 |
16 |
|
64 |
Вычесть |
2 |
10 |
4 |
10 |
|
65 |
Вычесть |
2 |
8 |
4 |
8 |
|
66 |
Вычесть |
2 |
16 |
4 |
16 |
|
67 |
Вычесть |
2 |
10 |
4 |
8 |
|
68 |
Вычесть |
2 |
10 |
4 |
16 |
|
69 |
Вычесть |
2 |
16 |
4 |
10 |
|
70 |
Вычесть |
2 |
16 |
4 |
8 |
|
71 |
Вычесть |
2 |
8 |
4 |
10 |
|
72 |
Вычесть |
2 |
8 |
4 |
16 |
25
3. Краткие сведения из теории
3. 1. Многобайтное сложение
Команды над битом переноса и команду ADC (сложение с переносом) можно использовать для сложения чисел произвольной длины без знака. Рассмотрим сложение двух 3-байтовых 16-ричных чисел (рис. 3).
|
32AF8AH |
|
|
|
32H |
|
|
|
|
|
AFH |
|
|
|
|
|
8AH |
|
||||||||||
+ |
|
|
|
|
|
+ 84H |
|
|
|
|
+ |
|
|
|
|
|
|
|
|
|
+ |
|
|
|
|
|||
84AA90H |
|
|
|
|
|
|
AAH |
|
|
|||||||||||||||||||
|
|
|
|
|
|
|
|
90H |
|
|||||||||||||||||||
= B75A1AH |
|
= B6H |
|
|
|
|
|
=59H |
|
|
|
|
|
|
|
|
|
|||||||||||
+ |
|
|
|
|
+ |
|
|
|
|
|
=1AH |
|
||||||||||||||||
01H |
|
|
|
01H |
|
|||||||||||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||||
|
|
|
|
|
|
= B7H |
|
|
|
|
=5AH |
|
|
|
|
|
Перенос=1 |
|
||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Пернос=1
Рис. 3. Сложение многобайтного числа
Это сложение можно выполнить путем сложения двух младших байтов данных чисел, а затем результирующий перенос прибавляют к двум старшим байтам и т. д. Рис. 4 иллюстрирует выполнение многобайтного сложения при следующих допущениях:
1.В регистре находится длина каждого прибавляемого числа (в данном случае – 3).
2.Слагаемые хранятся в памяти, начиная с младших байтов, по адресам FIRST и SECND соответственно.
3.Результат будет накапливаться от байта младшего разряда до байта старшего разряда с началом в ячейке памяти FIRST, заменяя первоначальное содержимое этих ячеек.
Память до сложения |
Память после сложения |
|||||||||||||
FIRST |
8A |
|
|
|
|
|
|
|
|
|
|
|
1A |
|
|
|
|
|
|
|
|
|
|
|
|
|
|||
FIRST+1 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
AF |
|
|
|
|
|
|
|
|
|
|
|
5A |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
FIRST+2 |
32 |
|
|
|
|
|
|
|
|
|
|
|
B7 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SECND |
90 |
|
|
|
|
|
|
|
|
|
|
|
90 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SECND+1 |
AA |
|
|
|
|
|
|
|
|
|
|
|
AA |
|
|
|
|
|
|
|
|
|
|
|
|
|
|||
SECND+2 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
84 |
|
|
|
|
|
|
|
|
|
|
|
84 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Рис. 4. Карта памяти при многобайтном сложении
3. 2. Многобайтное вычитание
Рассмотрим следующее вычитание двух двухбайтных 16-ричных чисел (табл. 19).
−1301H0503H
=0DFEH
26
Это вычитание можно выполнить путем вычитания двух младших байтов данных чисел, используя затем результирующий бит переноса для вычитания двух старших байтов, если имел место заем (используется команду SBB).
При вычитании младших байтов бит переноса (= 0) показывает отсутствие заема.
Таблица 19. Многобайтное вычитание
|
− |
00000001=01H |
|
|
|
|
11111101=- (03H +перенос) |
|
|
Вычитание младших байтов |
|
|
|
11111111=0FEH |
|
|
|
|
|
Бит переноса =1, указывая наличие заема |
|||
|
− |
00010011=13H |
|
|
|
|
11110101=- (05H +перенос) |
|
|
Вычитание старших байтов |
|
|
|
00001101=0DH |
|
|
|
|
|
Бит переноса сбрасывается |
, указывая отсутствие заема |
Всякий раз, когда имеет место заем, команда SBB инкрементирует вычитаемое на 1, что эквивалентно заему 1 из уменьшаемого. Для создания подпрограммы многобайтного вычитания необходимо продублировать подпрограмму много байтного сложения, заменяя команду ADC на команду SBB. Программа затем вычтет число, начинающееся в SECND, из числа, начинающегося в FIRST, помещая результат в FIRST.
3. 3. Десятичное сложение
Любую 4-битовую величину данных можно рассматривать как десятичную цифру 0…9, если не содержатся комбинации, соответствующие 16-ричным цифрам А…F. Для того чтобы сохранить эту десятичную интерпретацию при выполнении сложения, необходимо прибавлять 6 к 4-битовой величине всякий раз, когда сложение дает результат 10…15, т. к. каждая 4-битовая величина данных может содержать на шесть комбинаций больше, чем существует десятичных цифр.
Десятичное сложение выполняется при допущении, что каждый байт содержит две 4-битовые десятичные цифры. Байты суммируются в аккумуляторе по стандартному способу, а команда DAA (десятичная настройка аккумулятора) применяется затем для преобразования 8-байтового двоичного результата в правильное представление двух десятичных цифр.
Установка битов переноса и вспомогательного переноса также влияет на операцию DAA, что дает возможность складывать более чем двухзначные десятичные числа (табл. 20).
Таблица 20. Десятичное сложение
+2985D4936D
=7921D
Сброс бита переноса и прибавление двух младших цифр
+85H =10000101B
36H =00110110B
0BBH =10111011B
Перенос = 0 Вспомогательный перенос = 0
Выполнение команды DAA. Поскольку самые правые 4 бита >10D, то 6 будет прибавлено к аккумулятору
27
+ 0BBH =10111011B 6H =00000110B
0C1H =11000001B
Поскольку левые четыре бита теперь >10D, то 6 будет прибавлено к этим битам, устанавливая бит переноса
+ 0BBH =10111011B 60H =00110000B
21H =00100001B
Бит переноса = 1
Аккумулятор теперь содержит 21Н. Запоминаем эти две цифры
Складываем следующие две цифры
+ 29H =00101001B 49H =01001001B
73H =01110011B
Перенос = 0 Вспомогательный перенос = 1
Аккумулятор содержит 73Н
Выполнение команды DAA. Поскольку бит вспомогательного переноса установлен, то 6 будет прибавлено к аккумулятору
+ 73H =01110011B 6H =00000110B
79H =01111001B
Бит переноса =0
Поскольку самые левые 4 бита <10D, а бит переноса сброшен, то никаких дальнейших действий не происходит
Правильный десятичный результат равен 7921D
Подпрограмма сложения десятичных чисел аналогична подпрограмме многобайтного сложения и может быть получена из нее путем введения команды DAA после команды ADC M. Каждая итерация программного цикла складывает по две десятичные цифры данных чисел.
3. 4. Десятичное вычитание
Любую 4-битовую величину данных можно рассматривать как десятичную цифру 0…9, если не содержатся комбинации, соответствующие 16-ричным цифрам А…F. Команда DAA (десятичная настройка аккумулятора) может применяться для того, чтобы выполнить вычитание одного байта (представляющего 2 десятичные цифры) из другого, создавая двузначный десятичный результат. С помощью DAA можно производить вычитание многозначных десятичных чисел. Процесс состоит из получения дополнения до 100 вычитаемого и прибавление результата к уменьшаемому. Например, для вычитания 34D из 56D дополнение до 100 34D (100D – 34D = 66D) прибавляется к 56D. Получаем 122D, что при усечении до 8 битов дает 22D – правильный результат. Если посредством предшествующего вычитания был создан заем, то для компенсации заема создается дополнение вычитаемого до 99 (табл. 21, 22).
|
Таблица 21. Десятичное вычитание |
|
|
Шаг |
Действие |
1 |
Устанавливаем бит переноса в 1, что указывает на отсутствие заема |
2 |
Загружаем в аккумулятор 99Н, соответствующее по представлению 99D |
3 |
Прибавляем 0 к аккумулятору с переносом, получаем 99Н или 9АН, и бит |
переноса сбрасывается |
28
4 |
Вычитаем две цифры вычитаемого из аккумулятора, создавая дополнение |
до 99 или до 100 |
|
5 |
Прибавляем две цифры уменьшаемого к аккумулятору |
|
Используем команду DAA для проверки того, что результат в аккумуляторе |
6 |
находится в десятичном формате и для индикации заема с помощью бита |
|
переноса, если он имел место. Результат сохраняем |
7 |
Если вычитание должно быть продолжено для следующих цифр, перейти к |
|
шагу 2. В противном случае – останов |
Таблица 22. Пример десятичного вычитания
−4358D1362D
=2996D
Устанавливаем перенос = 1
Загружаем в аккумулятор 99Н
Прибавляем 0 с учетом бита переноса к аккумулятору
+99H =10011001B
+0H =00000000B
1H =00000001B
9AH =10011010B
Вычитаем цифры вычитаемого 62Н из аккумулятора
− 9AH =10011010B 62H = 01100010B
38H = 00111001B
Перенос = 1
Прибавляем цифры уменьшаемого 58Н к аккумулятору
+ 38H =00111000B 58H =01011000B
90H =10010000B
Перенос = 0 Вспомогательный перенос = 1
DAA преобразует аккумулятор в 96Н (поскольку вспомогательный перенос =1) и оставляет бит переноса равным 0, показывая, что имел место заем
Загружаем в аккумулятор 99Н. Прибавляем 0 с учетом бита переноса к аккумулятору. Аккумулятор равен 99Н
Вычитаем цифры вычитаемого 13Н из аккумулятора
−99H =10011001B
13H = 00010011B
86H =10000110B
Перенос = 1
Прибавляем цифры уменьшаемого 43Н к аккумулятору
+ 86H =10000110B 43H =01000110B
C9H =11001001B
Перенос = 0 Вспомогательный перенос = 0
DAA преобразует аккумулятор в 29Н и устанавливает бит переноса =1, показывая, что заема не произошло
Результат вычитания 1362D из 4358D будет 2996D
29
3. 5. Программная реализация умножения и деления
Умножение двух 8-битовых чисел без знака может быть выполнено посредством одного из двух способов: повторное сложение или применение операции регистрового сдвига. Повторное сложение обеспечивает простейший, но самый медленный способ умножения. Например, произведение 2АН×74Н может быть получено путем прибавления 74Н к аккумулятору (предварительно обнуленному) 2АН раз. Используя операцию сдвига, мы получаем более быстрое умножение. Сдвиг байта влево на 1 бит эквивалентен умножению на 2, а сдвиг байта вправо на 1 бит эквивалентен делению на 2. Следующий процесс дает правильный двухбайтный результат умножения однобайтного множимого на однобайтный множитель.
|
|
|
|
Таблица 23. Умножение |
|
|
|||
|
|
|
|
|
|
|
|
||
Шаг |
× |
2AH =00101010B |
|
Старший |
Младший |
||||
а/б |
|
|
|
|
|
байт резуль- |
байт резуль- |
||
|
3CH =00111100B |
||||||||
|
|
Действие |
|
|
|
тата |
тата |
||
|
|
9D8H =100111011000B |
|||||||
0 |
|
Начало |
|
0000 0000 |
0000 0000 |
||||
1 |
а |
Проверяем 0-й бит множителя; он равен 0 |
|
0000 0000 |
|
||||
|
б |
Сдвигаем 16-битовый результат вправо на 1 |
|
0000 0000 |
|||||
|
|
бит |
|
|
|
||||
2 |
а |
Проверяем 1-й бит множителя; он равен 0 |
|
0000 0000 |
|
||||
|
б |
Сдвигаем 16-битовый результат вправо на 1 |
|
0000 0000 |
|||||
|
|
бит |
|
0010 1010 |
|
||||
3 |
а |
Проверяем 2-й бит множителя; он равен 1. |
|
0000 0000 |
|||||
|
|
Прибавляем 2АН к старшему байту резуль- |
|
|
|
||||
|
|
тата |
|
0001 0101 |
|
||||
|
б |
Сдвигаем 16-битовый результат вправо на 1 |
|
0000 0000 |
|||||
|
|
бит |
|
0011 1111 |
|
||||
4 |
а |
Проверяем 3-й бит множителя; он равен 1. |
|
0000 0000 |
|||||
|
|
Прибавляем 2АН к старшему байту резуль- |
|
|
|
||||
|
|
тата |
|
0001 1111 |
|
||||
|
б |
Сдвигаем 16-битовый результат вправо на 1 |
|
1000 0000 |
|||||
|
|
бит |
|
0100 1001 |
|
||||
5 |
а |
Проверяем 4-й бит множителя; он равен 1. |
|
1000 0000 |
|||||
|
|
Прибавляем 2АН к старшему байту резуль- |
|
|
|
||||
|
|
тата |
|
0010 0100 |
|
||||
|
б |
Сдвигаем 16-битовый результат вправо на 1 |
|
1100 0000 |
|||||
|
|
бит |
|
0100 1110 |
|
||||
6 |
а |
Проверяем 5-й бит множителя; он равен 1. |
|
1100 0000 |
|||||
|
|
Прибавляем 2АН к старшему байту резуль- |
|
|
|
||||
|
|
тата |
|
0010 0111 |
|
||||
|
б |
Сдвигаем 16-битовый результат вправо на 1 |
|
0110 0000 |
|||||
|
|
бит |
|
|
|
||||
7 |
а |
Проверяем 6-й бит множителя; он равен 0 |
|
0001 0011 |
|
||||
|
б |
Сдвигаем 16-битовый результат вправо на 1 |
|
1011 0000 |
|||||
|
|
бит |
|
|
|
||||
8 |
а |
Проверяем 7-й бит множителя; он равен 0 |
|
0000 1001 |
|
||||
|
б |
Сдвигаем 16-битовый результат вправо на 1 |
|
1101 1000 |
|||||
|
|
бит |
|
|
|
1.Проверка самого младшего бита множителя. Если 0, то переход к следующему шагу. Если 1, то прибавить множимое к старшему байту результата.
2.Сдвиг всего двухбайтного результата вправо на один бит.
30