Программирование в машинных кодах и на языке ассемблера 1993 г.

Расширение системы команд процессора - арифметические конструкции.


2.1. АРИФМЕТИЧЕСКИЕ КОНСТРУКЦИИ 2.1.1. Сложение без учета флага переноса.

1. Прибавить к аккумулятору содержимое ячейки памяти. ADD A, (ADDR) LD HL, ADDR - указание на адрес

ADD A,(HL) - сложение

2. Десятиричное прибавление числа к аккумулятору. DADD A,N ADD A,N - сложение

DAA - перевод в десятиричную

форму

3. Десятиричное прибавление содержимого регистра к аккумулятору.

DADD A,reg ADD A,reg - сложение

DAA - перевод в десятиричную

форму

4. Прибавить 16-битное число к содержимому рег.пары HL. ADD HL, NN LD rp, NN - загрузка числа в ВС или DE.

ADD HL,rp - сложение

5. Прибавить 16-битное число к содержимому индексного регистра.

ADD xy,NN LD rp,NN - загрузка числа

ADD xy,rp - сложение

Регистровой парой может быть либо ВС либо DE.

6. Прибавить к регистру HL содержимое адреса двух смежных ячеек памяти.

ADD HL,(ADDR) LD rp,(ADDR) - загрузка числа

ADD HL,rp - сложение

7. То же, но для индексного регистра.

ADD xy, (ADDR) LD rp, (ADDR) - загрузка числа

ADD xy,rp - сложение

8. Прибавить содержимое ячеек памяти ADDR1, ADDR1+1 к содержимому ячеек памяти ADDR2, ADDR2+1.

ADD (ADDR2) , (ADDR1) LD HL, (ADDR2 ) - взять содержимое ADDR2

LD DE, (ADDR1) - взять содержимое ADDR1 ADD HL,DE - сложить их

LD (ADDR2) , HL - поместить сумму в ADDR2

9. Прибавить 16-битное число к содержимому адреса.

ADD (ADDR) , NN LD HL, (ADDR) - взять содержимое адреса

LD DE,NN - взять число

ADD HL,DE - сложить их

LD (ADDR) , HL - поместить сумму в адрес. 2.1.2. Сложение с учетом флага переноса.

10. Прибавить содержимое адреса к аккумулятору с учетом переноса.

ADC A, (ADDR) LD HL, ADDR - указание на адрес

ADC A, (HL) - сложение с учетом переноса

11. Прибавить к аккумулятору содержимое флага (переноса) .

ADC A,0

12. Десятиричное прибавление числа к аккумулятору с учетом флага переноса.

DADC A,N ADC A, N

DAA

13. Десятиричное прибавление содержимого регистра к аккумулятору с учетом флага переноса.

DADC A,reg ADC A,reg

DAA

14. Прибавление 16-битного числа к HL с учетом переноса. ADC HL,NN LD rp,NN

ADC HL, rp

15. Прибавление к регистру HL содержимого адреса с учетом переноса

ADC HL, (ADDR) LD rp, (ADDR)

ADC HL, rp

2.1.3. Команды вычитания без учета двоичного займа.

16. Вычесть содержимое адреса из аккумулятора. SUB (ADDR) LD HL, ADDR

SUB (HL)

17. Десятиричное вычитание числа из аккумулятора DSUB N SUB N

DAA

18. Десятиричное вычитание содержимого регистра из аккумулятора.

DSUB reg SUB reg

DAA

19. Вычесть содержимое регистровой пары из HL.

SUB HL,rp AND A - сброс флага переноса

SBC HL,rp - само вычитание

Необходимость во введении этой конструкции вызвана тем, что простого вычитания содержимого регистровой пары из HL без учета флага переноса в системе команд Z-80 нет. Приходится применять SBC, но предварительно обнулять флаг переноса.

2.1.4. Обратное вычитание.

20. Вычесть аккумулятор из числа, и результат поместить в аккумулятор.

SUB N,A NEG - изменение знака аккумулятора

ADD A,N - сложение (вместо вычитания)

ИЛИ

LD reg,A - запомнили аккумулятор LD A, N - ввели число в аккумулятор SUB reg - вычитание

21. Вычесть аккумулятор из регистра и результат поместить в аккумулятор.

SUB reg,A NEG

_ ADD A, reg

22. Десятиричное вычитание аккумулятора из числа. DSUB N,A LD reg,A - запомнили аккумулятор

LD A,N - ввели число

SUB reg - вычитание

DAA - перевод в десятиричную форму

23. Десятиричное вычитание аккумулятора из регистра. DSUB reg,A LD reg1,A

LD A,reg SUB reg1 DAA

2.1.5. Вычитание с двоичным займом (с учетом флага переноса)

24. Вычесть содержимое адреса из аккумулятора. SBC A, (ADDR) LD HL, ADDR - указали на адрес

SBC A, (HL) - вычитание с учетом флага C

25. Вычесть состояние флага С из аккумулятора.

SBC A,0

2 6.Десятиричное вычитание числа из аккумулятора с учетом C DSBC A, N SBC A, N

DAA

27. Десятиричное вычитание содержимого регистра из аккумулятора с учетом флага переноса.

DSBCV A,reg SBC A,reg

DAA

28. Вычитание двойного числа из HL с учетом флага переноса .

SBC HL, NN LD rp,NN

SBC HL,rp

2.1.6. Команды увеличения (инкремент) .

29. Выполнить инкремент для содержимого заданного адреса. INC (ADDR) LD HL, ADDR

INC (HL)

30. Инкремент аккумулятора с включением флага С, если в результате получается 0.

ADD A,1

О В отличие от команды INC команда ADD влияет на флаг пере

носа .

31. Десятиричный инкремент аккумулятора.

ADD A,1 DAA

32. Десятиричный инкремент регистра.

LD A,reg ADD A,1 DAA

LD reg,A

Необходимость переброски через аккумулятор вызвана тем, что команда DAA может применяться только к аккумулятору.

33. Инкремент содержимого двух смежных ячеек памяти. LD HL,(ADDR) INC HL

LD (ADDR) , HL

ИЛИ

LD HL,(ADDR) INC (HL) JR NZ,END INC HL INC (HL) DEC HL END: NOP

ПРИМЕЧАНИЕ:

а) В команде JR NZ,S мы вместо числа дали метку END. В реальной программе здесь, конечно же, надо будет подставить число, указывающее на сколько байтов вперед или назад надо перейти. Отметим, что применение метки позволяет не утруждать себя вычислением величины этого перехода. Все АССЕМБЛЕРы понимают назначение меток и, если Вы пишете свою программу в АССЕМБЛЕРе, то можете сильно упростить себе жизнь. Если же Вы программируете в маш. кодах вручную, то придется выполнить подсчет.

б) Мы привели два варианта выполнения требуемой команды. На глаз видно, что второй вариант значительно длиннее, т. е. занимает больше места в памяти. Интересно оценить быстродействие первого и второго вариантов. Для этого Вам может помочь наш может длиться 33 цикла или 51 цикл, в зависимости от того, произошло ли переполнение младшего байта после его приращения. Поскольку переполнение может произойти только в одном случае из 256, то наиболее вероятна ветвь, которая длится 33 цикла. Таким образом, мы имеем наглядный пример того, как программист может выбирать разные решения в зависимости от того, что ему важнее -экономия памяти или скорость работы.

котором приведено время выполнения каждой измеренное в тактовых циклах

"Справочник... " в команды процессора

LD HL, (ADDR)

(16)

LD

HL, ADDR

(10)

(10)

INC HL

( 6)

INC

(HL)

(11)

(11)

LD (ADDR) , HL

(16)

JR

NZ, END

(12)

( 7)

INC

HL

-

( 6)

38

INC

(HL)

-

(11)

DEC

HL

-

( 6)

33 51

Итак, первый вариант длится 38 тактовых циклов, а второй

2.1.7. Команды уменьшения (декремент) .

34. Уменьшить содержимое заданного адреса. DEC (ADDR) LD HL, ADDR

DEC (HL)

35. Декремент аккумулятора с включением флага С, если происходит двоичный заем.

SUB 1

36. Декремент аккумулятора с включением флага С, если двоичный заем не происходит.

ADD A, FF

37. Десятиричный декремент аккумулятора.

SUB 1

DAA

38. Десятиричный декремент регистра.

LD A,reg

SUB 1

DAA

LD reg,A

39. Декремент 16-битного числа, расположенного по адресу ADDR и ADDR+1.

LD HL,(ADDR)

DEC HL

LD (ADDR) , HL

40. Декремент 16-битного регистра с включением флага Z (флага нуля) , если в результате получается 0.

DEC rp

LD A,rpl - проверка на 0 с

OR rph выставлением флагов

41. Умножение аккумулятора на 2.

ADD A,A

42. Умножение аккумулятора на 3.

LD reg,A - запомнили аккумулятор

ADD A, A - умножили аккумулятор на 2

ADD A,reg - прибавили к результату содержимое аккумулятора еще раз.

43. Умножение аккумулятора на 4.

ADD A,A ADD A,A

Те же приемы могут быть применены и для умножения на другие малые целые числа.

44. Умножение содержимого регистра на 2.

SLA reg

45. Умножение содержимого регистра на 4.

SLA reg SLA reg

Примечание: поскольку инструкция SLA - двухбайтная, все же быстрее перемещать содержимое регистра в аккумулятор и выполнять умножение через однобайтную команду ADD A, A. Вычисления выполняются почти в три раза быстрее.

46.

Умножить

на 2

содержимое

регистра HL.

ADD

HL, HL

47 .

Умножить

на 3

содержимое

регистра HL.

LD

rph, H

- запомнили старший

LD

rpl, L

- запомнили младший

ADD

HL, HL

- умножили на 2

ADD

HL, rp

- умножили на 3

48.

Умножить

на 2

содержимое

индексного регистра

ADD

xy, xy

49.

Умножить

на 2

16-битное

число, находящееся в

адресе.

LD

HL,ADDR

- указание на адрес

SLA

(HL)

- умножили на 2 младший байт

INC

HL

- перешли к старшему байту

RL

(HL)

- умножили на 2 старший байт

Обратите внимание на то, что при умножении старшего байта мы использовали команду RL, а не SLA. Это необходимо, чтобы "прихватить" и содержимое флага переноса, т. к. при умножении на 2 младшего байта мог ведь возникнуть и перенос единицы, которую надо учесть в старшем байте.

Второй вариант этой конструкции: LD xy,ADDR SLA (XY+0) RL (XY+1)

2.1.9. Команды деления.

50. Деление аккумулятора пополам (без знака).

SRL A

51. То же, но со знаком.

SRA A

52. Деление аккумулятора на 4 (без знака) .

SRL A SRL A

ИЛИ ТО ЖЕ САМОЕ, НО БЫСТРЕЕ RRA RRA

AND 3F

В результате ротации два младших бита перейдут в старшие. Теперь надо их очистить, что и делается маскированием их командой AND 0011 1111. Обратите внимание, что 0011 1111В = 3FH.

53. Деление на 2 16-битного содержимого адреса.

LD xy,ADDR

SRL (xy+1) - деление старшего байта

RR (XY+0) - деление младшего байта с

"прихватыванием" флага С.

54. Деление содержимого регистра на 2 (без знака) .

SRL rph RR rpl

55. То же, но со знаком.

SRA rph RR rpl

56. Сравнить аккумулятор с числом. Включить в результате биты в тех позициях, где они отличаются.

XOR N

57. Сравнить регистровую пару rp с HL. Если rp больше, включить флаг переноса, в противном случае - выключить.

CP rp, HL AND A - сброс флага С

SBC HL, rp

58. Сравнить HL с двухбайтным числом. CP HL, NN AND A

LD rp,NN SBC HL, rp

59. Сравнить содержимое регистровой пары с двухбайтным числом, находящимся по заданному адресу.

CP rp,(ADDR) AND A

LD HL,rp LD rp,(ADDR) SBC HL, rp

60. То же, но для индексного регистра.

CP xy, (ADDR) PUSH xy - переброска содержимого в HL

POP HL при посредстве стека

AND A

LD rp,(ADDR) _ SBC HL, rp

61. Сравнить указатель стека с 16-битным числом. CP SP, NN LD HL, 0 - очистка HL

ADD HL,S P - переброска SP в HL

LD rp,-NN ADD HL, rp

62. Сравнить указатель стека с 16-битным числом, находящимся в указанном адресе.

CP SP,(ADDR) LD HL,0

ADD HL , S P LD rp,(ADDR) AND A SBC HL, rp

2.1.11. Изменение знака (в двоичной дополнительной форме)

63. Изменение знака регистра.

- обнуление аккумулятора

- формирование -reg в аккум-ре

- формирование -reg в регистре

SUB A SUB reg LD reg A

LD A,reg NEG

LD reg,A

NEG reg

ИЛИ

64. Изменение знака в заданном адресе.

SUB A

LD HL,ADDR SUB (HL) LD (HL),A

NEG (ADDR)

ИЛИ

LD HL,ADDR LD A,(HL) NEG

LD (HL),A

65. Изменение знака регистровой пары.

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

- инвертировали младший байт

- прибавили 1 для получения результата.

LD A,rph CPL

LD rph,A LD A,rpl CPL

LD rpl, A INC rp

NEG rp

LD HL, 0 AND A SBC hl, rp

ИЛИ

66. Изменение знака 16-битного числа, находящегося в указанном адресе.

NEG (ADDR) LD HL,0

LD rp,(ADDR) AND A SBC HL, rp LD (ADDR) , HL

67. Дополнение до 99. (Т.е. вычисление 99 -"А")

LD reg,A LD A,99 SUB reg

Давать команду DAA здесь не нужно, поскольку если к началу операции в аккумуляторе находилось правильное BCD-число, то и 99 минус аккумулятор тоже будет правильным BCD-числом.

68. Дополнение до 100.

NEG DAA

2.1.12. Команды преобразований.

69. Преобразовать содержимое аккумулятора в 16-битное число без знака и записать его в регистровой паре.

LD rpl,A

LD rph,0

70. То же, но со знаком.

Напомним, что в двоичной дополнительной форме, которая применяется для записи целых чисел со знаком, старший (седьмой, он же левый) бит является знаковым.

LD rpl,A

знаковый бит переносится во флаг переноса С. в аккумуляторе остается ноль минус флаг С.

ADD A,A

SBC A, A

LD rph,A

71. Преобразование содержимого заданного адреса в 16-битную форму со знаком.

LD HL,ADDR - указание на адрес

LD A, (HL) - взяли число

ADD A,A - перевод знакового бита в С

SBC A,A - формирование знакового байта

INC HL - указание на старший байт

LD (HL) ,A - установка старшего байта

72. Приведение аккумулятора по младшему биту. Если младший бит равен нулю, то в аккумуляторе выставляется 0, а если он равен единице, то FF.

RRA - младший бит переносится в С

SBC A,A - формирование (0 минус флаг С)

73. Приведение аккумулятора по знаку. Если в аккумуляторе положительное число, то в нем выставляется 0, а если отрицательное, то FF.

ADD A,A - знаковый бит переносится в C

SBC A, A




СОДЕРЖАНИЕ:


  Оставте Ваш отзыв:

  НИК/ИМЯ
  ПОЧТА (шифруется)
  КОД



Темы: Игры, Программное обеспечение, Пресса, Аппаратное обеспечение, Сеть, Демосцена, Люди, Программирование

Похожие статьи:
Реклама - реклама и объявления.
О людях - Спектрум мертв. Это однозначно и не поддается сомнениям. Jаson Kruеgеr рецензирует деятельность Ubeliever'a.
Истории - милицейские байки, продолжение.
Юмор - Анекдоты.
Editorial - "В этом году "Крику" исполняется 10 лет. Этот юбилей мы решили отметить достаточно своеобразно - взяли и возродили журнал".

В этот день...   3 декабря