Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Методы / Мышев А.В. (ч.2)

.pdf
Скачиваний:
29
Добавлен:
11.06.2015
Размер:
580.8 Кб
Скачать

Предполагается, что при вызове подпрограммы регистр HL адресует делимое, регистр DE – делитель, а в регистре В находится число байтов операндов. Подпрограмма начинается с проверки длины операндов и сразу осуществляет возврат, если она равна нулю. Затем формируется и запоминается в слове COUNT счетчик битов, а обе буферные области очищаются. С помощью команд SHLD производится инициализация слов PTRl и PTR2, служащих указателями буферов.

Программа 5.11. Деление беззнаковых чисел произвольной длины

;Начальный адрес делимого в HL, начальный адрес делителя

;в DE, длина операндов в регистре В. Частное возвращается на место

;делимого, а HL адресует положительный остаток.

;Если делитель равен нулю, флажок переноса установлен в единице.

DIVRND:

 

; Проверить нулевую длину сомножителей.

 

MOV

A, B

; Передать длину в аккумулятор

 

ORA

A

: Возврат

 

JZ

OK

; Возврат, если она равна нулю

 

SHLD

DVEND

; Сохранить адрес делимого

 

XCHG

 

; Сохранить

 

SHLD

DVSOR

;

адрес делителя

 

MOV

C, B

; Сохранить длину в регистре С

 

; Отобразить счётчик битов и сохранить его в слове COUNT

 

MOV

L,C

;В HL длина в байтах

 

MVI

H,0

 

 

 

DAD

H

; Умножить ее на 8

 

DAD

H

;

для образования счётчика битов

 

DAD

H

 

 

 

INX

H

;

 

SHLD:

COUNT

 

; Сохранить счётчик битов

 

; Очистить буферые области

 

 

LXI

H,BUFF1

 

; Начальные адреса буферов

 

LXI

H,BUFF2

 

; в HL и DE

 

MOV

B, C

; Длина в регистре В

 

SUB

A

;Сбросить аккумулятор

ZERO:

MOV

M, A

; Передать ноль в текущие байты

 

STAX

D

;

в текущие байты буферов

 

INX

H

; Продвинуть указатели

 

INX

D

 

 

 

DCR

B

; Декремент счетчика байтов

 

; Инициировать указатели буферов

 

LXI

H,BUFF1

; Адрес первого текущего буфера

 

SHLD

PTR1

;

в слове PTR1

51

 

LXI

H,BUFF2

; Адрес второго текущего буфера

 

SHLD

PTR2

;

в слове PTR2

 

; Проверить делитель на ноль

 

 

LHLD

DVSOR

; В HL адрес делителя

 

MOV

B, C

; Счетчик битов в регистре В

 

SUB

A

; Сбросить аккумулятор

CHECK: ORA

M

; Объеденить по ИЛИ очередной байт

 

INX

H

; Продвинуть указатель

 

DCR

B

; Декремент счетчика байтов

 

JNZ

CHECK

; Повторить до завершения

 

DRA

A

; Проверить на ноль

 

JZ

ERR

; Ошибка, делитель равен нулю

 

; Подготовка к циклу деления закончена

 

ORA

А

; В начале флажок переноса сброшен

LOOP:

LHLD

DVSOR

; Начальный адрес делителя в DE

 

XCHG

 

 

 

 

LHLD

DVEND

; Начальный адрес делимогов HL

 

MOV

B, C

; Счетчик байтов в регистре В

 

; Сдвинуть делимое влево с учетом флажка переноса

SHIFT1: MOV

A, M

; Сдвинуть очередной байт

 

RAL

 

;

делимого

 

MOV

M, A

;

влево

 

INX

H

; Продвинуть указатель

 

DCR

B

; Декремент счетчика байтов

 

JNZ

SHIFT1

; Повторять до завершения

 

; Проверить достижение конца цикла деления

DECR:

LDA

COUNT

; Произвести декремент счетчика

 

DCR

A

;

битов (слова)

 

STA

COUNT

; и перейти на метку ОК,

 

JNZ

COUNT

; если деление закончено.

 

LDA

COUNT+1

 

; Эти команды не изменяют

 

DCR

A

; состояние флажка переноса

 

STA

COUNT+1

 

 

 

JM

OK

; Деление закончено

CONT:

; Сдвинуть содержимое текущего буфера влево,

 

; передать флажок переноса в младший бит.

 

LHLD

PTR1

; Сохранить флажок переноса

 

MOV

B, C

; Проверить на ноль старший байт

SHIFT2: MOV

A, M

;

счетчика битов

 

RAL

 

;

битов (слова)

 

MOV

M, A

; и перейти на метку ОК,

 

INX

H

; если деление закончено.

 

DCR

B

; Эти команды не изменяют

 

JNZ

SHIFT2

; Повторять до завершения

; Произвести вычитание, помещая разность в другой

52

 

PUSH

B

; Сохранить длину, освободить ВС

 

MOV

A, C

; Образовать счетчик байтов

 

STA

LENGTH

; в ячейке LENGTH

 

LHLD

PTR2

; В HL указатель другого буфера

 

MOV

C, L

;

передать его в ВС

 

MOV

B, H

 

 

 

LHLD

PTR1

; В HL указатель текущего буфера

 

XCHG

 

;

передать его в DE

 

LHLD

DVSOR

; В HL адрес делителя

 

ORA

A

; Сбросить флажок заема

SUBL:

LDAX

D

; Произвести вычитание

 

SBB

M

;

и заполнить разность

 

STAX

B

 

 

 

INX

H

; Продвинуть указатели

 

INX

D

 

 

 

INX

B

 

 

 

LDA

LENGTH

; Декркмент счетчика байтов

 

DCR

A

 

 

 

STA

LENGTH

 

 

 

JNZ

SUBL

; Повторять до завершения

 

POP

B

; Восстановить длину операндов

 

;Во флажке переноса инверсия бита частного

 

CMC

 

; Образовать явный бит частного

 

JNC

LOOP

; Разность отрицательна

 

LHLD

PTR1

; Разность положительна

 

XCHG

 

;

необходимо скоммутировать

 

LHLD

PTR2

;

буферы (обменять содержимое слов

 

SHLD

PTR1

; PTR1 и PTR2)

 

XCHG

 

 

 

 

SHLD

PTR2

 

 

 

JMP

LOOP

; Повторять цикл деления

ERR:

; Ошибка - деление на ноль

 

 

 

STC

 

; Установить флажок переноса

 

JMP

EXIT

 

 

OK:

; состояние флажка переноса

 

 

ORA

A

; Сбросить флажок переноса

 

LHLD

PTR1

; В HL начальный адрес остатка

 

RET

 

; Возвратт

Далее осуществляется проверка делителя на ноль и, если делитель равен нулю, подпрограмма возвращается с установленным в 1 флажком переноса (метка ERR). Начиная с метки LOOP реализован «глобальный» цикл деления с образованием последовательных битов частного. Первое действие в цикле заключается в сдвиге де-

53

лимого на один бит влево (метка SHIFT1), причем выдвигаемый бит попадает во флажок переноса. После этого производится декремент счетчика битов и при достижении им нуля подпрограмма заканчивается. Если цикл деления не закончен, осуществляется сдвиг влево содержимого текущего буфера (метка SHIFT2), а затем из него вычитается делитель (метка SUBL). Как уже говорилось, формируемая разность помещается в другой буфер. В зависимости от полученной цифры частного (она определяется состоянием флажка переноса) производится (или нет) коммутация буферов, и цикл деления повторяется.

Деление знаковых целых чисел обычно выполняется следующи-

ми действиями: по знакам делимого и делителя определяется знак частного; образуются абсолютные значения операндов, т.е. операнды превращаются в беззнаковые числа, для деления которых привлекается любая из рассмотренных выше подпрограмм; с учетом знака частное представляется в дополнительном коде.

ГЛАВА 6. ОПЕРАЦИИ С ДЕСЯТИЧНЫМИ ЧИСЛАМИ

При решении некоторых задач приходится оперировать многоразрядными десятичными числами, которые, как правило, представлены в формате упакованных целых беззнаковых чисел. В МП К580 для десятичной арифметики предусмотрена единственная команда DAA десятичной коррекции аккумулятора. Она воздействует на находящуюся в аккумуляторе двоичную сумму двух байтов, содержащих упакованные десятичные числа, таким образом, что в аккумуляторе получается упакованное десятичное представление суммы, и флажок переноса показывает правильный десятичный перенос. Благодаря этой команде легко реализуются операции сложения и вычитания, но в операциях умножения и деления появляются некоторые трудности.

6.1. Сложение и вычитание

Рассмотренную выше программу 5.1 сложения двоичных целых беззнаковых чисел произвольной длины очень легко превратить в

54

программу сложения десятичных чисел: для этого достаточно после команды двоичного сложения ADC ввести команду DAA.

Установленный в 1 флажок переноса при возврате из подпрограммы сигнализирует о переполнении.

Вычитание упакованных десятичных чисел несколько усложняется тем обстоятельством, что команда DAA не корректирует результат двоичного вычитания, поэтому операцию приходится выполнять в два этапа: сначала образуется дополнение вычитаемого до 10n+l (т.е. десятичный дополнительный код), а затем полученное число суммируется с уменьшаемым. Результаты сложения можно корректировать командой DAA. В программе 6.1 приняты такие же начальные условия, как и в программе 5.1.

Программа 6.1. Сложение упакованных десятичных целых без- знаковых чисел

;Начальные адреса операндов находятся в регистрах ;HL и DE, длина (в байтах) в регистре B.

;Сумма замещает операнд, адресуемый регистром DE

;

 

 

ADDPCK:

XRA A

;Сбросить флажки переноса

LOOP:

LDAX D

;Текущий байт первого операнда

 

ADC M

;Прибавить байт второго операнда

 

DAA

;Скорректировать сумму

 

STAX D

;Сохранить текущий байт суммы

 

IHX H

;Продвинуть указатели

 

IHX D

 

 

DCR B

;Декремент счетчика байтов

 

JNZ LOOP

;Повторять до завершения

 

RET

;Возврат

В этой подпрограмме оригинально используется команда обмена XCHG (обменивается содержимое регистров HL и DE), благодаря которой можно обращаться к памяти короткими командами ADD М и MOV М, А. Если не использовать такого приема, в подпрограмме появляются дополнительные команды межрегистровых передач.

Образование десятичного дополнительного кода вычитаемого и сложение его с уменьшаемым реализовано в одном цикле. Десятичный дополнительный код получается путем вычитания из девяток и инкремента результата, поэтому до входа в цикл флажок переноса устанавливается в 1 командой STC. Следовательно, только

55

младший байт вычитаемого вычитается не из 99, а из 100, что эквивалентно инкременту результата. Признаком получения отрицательной разности является сброшенный в ноль флажок переноса.

6.2. Умножение

Программа 6.2. Вычитание упакованных десятичных целых беззнаковых чисел

;Адрес уменьшаемого в регистре DE, адрес вычитаемого

;в регистре HL, длина операндов (в байтах) – в регистре B. ;Разность замещает уменьшаемое.

;

 

 

 

SUBNPK:

STC

 

;Для младшего байта флажок =1

LOOP:

MVI

A,99H

;Загрузить девятки

 

ACI

0

;Учесть флажок переноса

 

SUB

M

;Дополнение вычитаемого

 

XCHG

 

;Обменять указатели операндов

 

ADD

M

;Сложить с уменьшаемым

 

DAA

 

;Скорректировать как сумму

 

MOV

M,A

;Разность на месте уменьшаемого

 

XCHG

 

;Восстановить указатели

 

IHX

H

;Продвинуть указатели

 

IHX

B

 

 

DCR

B

;Декремент счетчика байтов

 

JNZ

LOOP

;Повторять до завершения

 

RET

 

;Возврат

При умножении упакованных десятичных чисел сохраняется общий принцип выполнения операции с двоичными числами: накапливающее суммирование множимого в зависимости от значений цифр множителя (см. рис. 5.2). Однако по сравнению с умножением двоичных чисел появляются некоторые особенности.

Во-первых, основной единицей обработки операндов становится десятичная цифра, т.е. четыре бита, например, сдвиги множимого и суммы частичных произведений необходимо осуществлять в цикле на четыре бита. Во-вторых, при умножении на каждую цифру множителя множимое прибавляется такое количество раз, равное значению цифры множителя (нулевые цифры, естественно, пропускаются). Каждое суммирование сопровождается командой десятичной коррекции DAA. Программа десятичного умножения содержит около 120 команд (в тексте не приводится).

56

6.3.Деление

Воперации деления упакованных десятичных чисел также со-

храняется общий принцип выполнения операции с двоичными числами: последовательные вычитания делителя из остатков (см. рис. 5.4). Но здесь, как и в операции умножения, появляются некоторые отличия. Основной единицей обработки операндов остается десятичная цифра, поэтому сдвиги остатка и частного производятся на четыре бита. При вычитании делителя из остатка фиксируется число вычитаний до получения отрицательной разности; это число вычитаний и является очередной цифрой частного. Явное вычитание заменяется операцией сложения остатка с десятичным дополнительным кодом делителя. Длина программы деления десятичных чисел произвольной длины, как и программы умножения, составляет около 120 команд.

Знаковые упакованные десятичные числа представляются в десятичном дополнительном коде. В этом формате сложение и вычитание выполняются аналогично соответствующим операциям над беззнаковыми упакованными десятичными числами (см. программы 6.1 и 6.2). Результат представляется в десятичном дополнительном коде. Умножение и деление обычно выполняются над абсолютными значениями операндов, а знак результата определяется отдельным действием.

Операции с неупакованными десятичными числами на практике почти не встречаются. Рассмотрим все же выполнение сложения и вычитания беззнаковых целых чисел в этом формате. Напомним, что байт содержит 16-ричные коды от 30Н до З9Н, соответствующие десятичным цифрам от 0 до 9. При сложении таких чисел с произвольной длиной операция начинается с младших байтов и циклически продолжается в сторону старших байтов с учетом межразрядных переносов. Команда ADC позволяет учесть межразрядный перенос, сформированный во флажке переноса. Однако фактический межразрядный перенос должен быть десятичным переносом из младшей тетрады суммируемых байтов. Поэтому в программе потребуются специальные команды, передающие межтетрадный перенос во флажок переноса. Если произвести двоичное сложение

57

двух байтов, а затем скорректировать сумму командой DAA, то интересующий нас перенос будет зафиксирован в четвертом бите аккумулятора. Его состояние необходимо передать во флажок переноса; эту функцию выполняют команды ANI, CPI и СМС.

Программа 6.3. Сложение неупакованных десятичных целых 6еззнаковых чисел

;Начальные адреса операндов находятся в регистрах ;HL и DE, длина в регистре B.

;Сумма замещает операнд, адресуемый регистром DE

;

 

 

 

ADUNPK:

XRA A

;Сбросить флажок переноса

 

PUSH PSW

;Сохранить его в стеке

LOOP:

POP PSW

;Возвратить состояние переноса

 

LDAX D

;Текущий байт первого операнда

 

ADC M

;Прибавить байт второго операнда

 

DAA

;Скорректировать сумму

 

ANI 1FH

;Выделить нужные биты

 

CPI 16

;Передать межразрядный перенос

 

CMC

;

во флажок переноса

 

PUSH PSW

;Сохранить перенос в стеке

 

ORI 30H

;Образовать код цифры

 

LDAX D

;Сохранить текущай байт суммы

 

IHX H

;Продвинуть указатели

 

IHX D

;

 

 

DCR B

;Декремент счетчика

 

JNZ LOOP

;Повторять до завершения

 

POP PSW

;Вернуть значение переноса

 

RET

;Возврат

 

После команды десятичной коррекции DAA выделяются пять младших битов (команда ANI) и находящееся в них число сравнивается с 16 (команда CPI). Если оно больше или равно 16, флажок переноса сбрасывается в ноль (но десятичный перенос должен быть равен единице), а если число в аккумуляторе меньше 16, флажок переноса устанавливается в 1 (десятичный же перенос должен быть равным 0). Поэтому команда СМС инвертирования флажка переноса образует в нем правильное значение десятичного переноса. Командой PUSH PSW оно сохраняется в стеке, т.к. следующая команда ORI З0Н, образующая в аккумуляторе код цифры суммы, сбрасывает флажок переноса в 0. Следующие команды стандартным образом завершают цикл суммирования. При выходе из подпро-

58

граммы установленный в 1 флажок переноса означает переполнение. Вычитание неупакованных десятичных чисел приводится к сложению путем образования десятичного дополнительного кода вычитаемого. Отметим, что здесь команда СМС не требуется.
Программа 6.4. Вычитание неупакованных десятичных целых беззнаковых чисел
;Адрес уменьшаемого в регистре DE, адрес вычитаемого ;в регистре HL, длина операнда – в регистре B.
;Разность замещает уменьшаемое.
;
SUBNPK: STC ;Для младшего байта флажок =1
PUSH PSW ;Сохранить его в стеке
LOOP: POP PSW ;Возвратить состояние переноса MVI A,99H ;Загрузить девятки
ACI 0 ;Учесть флажок переноса
SUB M ;Дополнение вычитаемого XCHG ;Обменять указатели операндов ADD M ;Сложить с уменьшаемым DAA ;Скорректировать как сумму ANI 1FH ;Выделить нужные биты
CPI 16 ;Определить состояние переноса PUSH PSW ;Сохранить перенос в стек
ORI 30H ;Образовать код цифры
MOV M,A ;Разность на месте уменьшаемого XCHG ;Восстановить указатели
IHX H ;Продвинуть указатели
IHX D
DCR B ;Декремент счетчика байтов
JNZ LOOP ;Повторять до завершения
POP PSW ;Вернуть значение переноса RET ;Возврат
59

ЛИТЕРАТУРА

1.Майров С.А., Новиков Г.Н. Принципы организации цифровых машин.

– Л.: Машиностроение, 1974. – 431с.

2.Майров С.А.,Новиков Г.Н. Структура электронных вычислительных машин.– Л: Машиностроение, 1979. – 385 с.

3.Мышев А.В. Структурная архитектура и принципы построения процессорных и запоминающих устройств. – Обнинск: ИАТЭ, 1999. – 76 с.

4.Каган Б.М. Электронные вычислительные машины и системы. – М.: Энергоатомиздат, 1991. – 591 с.

5.Преснухин Л.Н., Нестеров П.В. Цифровые вычислительные машины: Учебное пособие для вузов. – М.: Высшая школа, 1991. – 583 с.

6.Савельев А.Д. Прикладная теория цифровых автоматов: Учебник для вузов. – М.: Высшая школа, 1987. – 272 с.

7.Терехова В.Г., Мышев А.В. Методические указания к выполнению лабораторных работ по курсу «ЭВМ» – Обнинск: ИАТЭ, 1993. – 25 с.

СОДЕРЖАНИЕ

ПРЕДИСЛОВИЕ ………………………………………………………….. 3

ГЛАВА 4. АРИФМЕТИЧЕСКИЕ ОПЕРАЦИИ В ПРОЦЕССОРНОЙ СИСТЕМЕ НА БАЗЕ

ЧИПА КР580ИК80 ………………………………………... 4

4.1.ОБЩАЯ ХАРАКТЕРИСТИКА “ЧИПА” КР580ИК80 …………… 4

4.2.ПРОГРАММНАЯ МОДЕЛЬ ПРОЦЕССОРНОЙ СИСТЕМЫ …………………………………………………………. 7

4.3.СИСТЕМА КОМАНД ПРОЦЕССОРНОЙ СИСТЕМЫ …………. 18

4.4.АЛГОРИТМЫ И ПРОГРАММЫ АРИФМЕТИЧЕСКИХ

ОПЕРАЦИЙ ………………………………………………………… 29

ГЛАВА 5. ОПЕРАЦИИИ НАД ДВОИЧНЫМИ ЦЕЛЫМИ ЧИСЛАМИ В ПРОЦЕССОРНОЙ СИСТЕМЕ

КР580ИК80 …………………………………………………... 30

5.1.СЛОЖЕНИЕ И ВЫЧИТАНИЕ ………………………….………… 30

5.2.УМНОЖЕНИЕ ……………………………………………………... 35

5.3.УМНОЖЕНИЕ ДВОИЧНЫХ ЦЕЛЫХ БЕЗЗНАКОВЫХ

ЧИСЕЛ, ИМЕЮЩИХ ПРОИЗВОЛЬНУЮ ДЛИНУ ….………… 40 5.4. ДЕЛЕНИЕ …………………………………………………………... 46

ГЛАВА 6. ОПЕРАЦИИ С ДЕСЯТИЧНЫМИ ЧИСЛАМИ .………… 54

6.1.СЛОЖЕНИЕ И ВЫЧИТАНИЕ ………………………….………… 54

6.2.УМНОЖЕНИЕ ……………………………………………………... 56

6.3.ДЕЛЕНИЕ …………………………………………………………... 57 ЛИТЕРАТУРА ……………………………………………………………. 60

60