Разработка программ с использованием многобайтных чисел, Организация операции вычитания, логические операции

 

     Если в ассемблере конкретного микроконтроллера не предусмотрена операция вычитания, то один из способов реализации этой операции (назовем его первым способом) основан на представлении вычитаемого в виде дополнительного кода (инверсный + 1), т.е. А-В=А+(-В). Например, необходимо решить следующую задачу: (R6)ß(R5) - (R4). Тогда, в общем виде:

;(R6)ß(R5) - (R4)

MOV A,R4;     (A)ß(R4)

     CPL A;          (A)ßnot(A)

     INC A;          (A)ß(A)+1

     ADD A,R5;     (A)ß(A)+(R5)

     MOV R6,A;     (R6)ß(A).

     Чтобы убедиться в правильности алгоритма, рассмотрим предыдущий пример с конкретными числами: 8EH - 5FH (8EH - 5FH=2FH).

  A R4 R5 R6 C
  00H 5FH 8EH 00H 0
MOV A,R4 5FH - - - -
CPL A A0H - - - -
 INC A A1H - - - -
ADD A,R5 2FH - - - 1
MOV R6,A 2FH 5FH 8EH 2FH 1

     A0H=not(5FH) или 10100000B=not(01011111B);

     A1H=A0H + 01H;

     12FH=A1H + 8EH, причем (C)ß1, (A)ß2FH.

 

     Следует заметить, что при реализации операции вычитания по первому способу при положительной разности в старшем разряде появляется единица, выходящая за рамки диапазона (в данном случае эта

 

единица попадает в С). При отрицательной же разности результат получается в дополнительном коде (а в С получается ноль). Например, необходимо вычислить 5FH – 8EH.

  A R4 R5 R6 C
  00H 8EH 5FH 00H 0
MOV A,R4 8EH - - - -
CPL A 71H - - - -
 INC A 72H - - - -
ADD A,R5 D1H - - - -
MOV R6,A D1H 8EH 5FH D1H 0

71H=not(8EH) или 01110001B=not(10001110B);

     72H=71H + 01H;

     D1H=72H + 5FH.

Таким образом, 5FH – 8FH=D1H. Но если D1H представить как отрицательное число, то получим:

     not(D1H)=2EH или not(11010001B)=00101110B;

     2FH=2EH+01H.

Т.е. получается D1H= - 2FH или 5FH – 8EH= -2FH.

Еще один способ реализации операции вычитания (назовем его вторым способом) реализует следующий алгоритм А-В=not(not(A)+B). Это эквивалентно (но не равнозначно) А-В= - (-A+B). Тогда, решение предыдущей задачи в общем виде по второму способу:

;(R6)ß(R5) - (R4)

MOV A,R5;     (A)ß(R5)

     CPL A;      (A)ßnot(A)

     ADD A,R4;     (A)ß(A)+(R4)

     CPL A;          (A)ßnot(A)

     MOV R6,A;     (R6)ß(A).

Теперь два примера с конкретными числами: 8EH - 5FH и 5FH – 8EH.

  A R4 R5 R6 C
  00H 5FH 8EH 00H 0
MOV A,R5 8EH - - - -
CPL A 71H - - - -
ADD A,R4 D0H - - - -
CPL A 2FH - - - -
MOV R6,A 2FH 5FH 8EH 2FH 0

71H=not(8EH) или 01110001B=not(10001110B);

     D0H=71H + 5FH;

2FH=not(D0H) или 00101111B=not(11010000B).

  A R4 R5 R6 C
  00H 8EH 5FH 00H 0
MOV A,R5 5FH - - - -
CPL A A0H - - - -
ADD A,R4 2EH - - - 1
CPL A D1H - - - -
MOV R6,A D1H 8EH 5FH D1H 1

A0H=not(5FH) или 10100000B=not(01011111B);

     12EH=A0H + 8EH, причем (C)ß1, (A)ß2EH

D1H=not(2EH) или 11010001B=not(00101110B).

По второму способу при положительной разности результат получается "чисто", а в С получается ноль. При отрицательной же разности результат получается в дополнительном коде, а в С попадает единица.

Сравнение двух чисел можно произвести путем нахождения разности между первым и вторым числами, например, с помощью второго способа. Если при этом признак переполнения (С)=0, то первое число больше или равно второму, а если (С)=1, то первое меньше второго. Далее по содержимому С можно организовать соответствующее ветвление в программе. Допустим, в аккумулятор требуется записать максимальное значение содержимого одного из двух регистров R4 или R6. Тогда, решение задачи в общем виде:

;(A)ßmax [(R4), (R6)]

MOV A,R4;     (A)ß(R4)

     CPL A;          (A)ßnot(A)

     ADD A,R6;     (A)ß(A)+(R4)

     CPL A;          (A)ßnot(A) – не обязателен

JNC M1;        переход при (C)=0, т.е. когда (R4)>=(R6)

MOV A,R6;     иначе, при (C)=1 (A)ß(R6), т.е. когда (R4)<(R6)

JMP M2;        и обход альтернативного действия

M1: MOV A,R4;     (A)ß(R4) при (C)=0, т.е. когда (R4)>=(R6)

M2: NOP;               пустой оператор или продолжение программы.

     Если само значение разности не нужно, то второй оператор CPL A не обязателен, т.к. он не влияет на содержимое признака С.

Теперь два примера этой же задачи с конкретными числами.

  A R4 R6 C
  00H 98H 3CH 0
 MOV A,R4 98H - - -
 CPL A 67H - - -
 ADD A,R6 A3H - - -
JNC M1 - - - -
MOV A,R6        
JMP M2        
M1: MOV     A,R4 98H - - -
M2: NOP 98H 98H 3CH 0

67H=not(98H) или 01100111B=not(10011000B);

     A3H=67H + 3CH, причем (C)=0.

 

  A R4 R6 C
  00H 3СH 98H 0
 MOV A,R4 3СH - - -
 CPL A С3H - - -
 ADD A,R6 5BH - - 1
JNC M1 - - - -
MOV A,R6 98H - - 1
JMP M2 - - - -
M1: MOV     A,R4        
M2: NOP 98H 3CH 98H 1

С3H=not(3СH) или 11000011B=not(00111100B);

15BH=С3H + 98H, причем (C)ß1, (A)ß5BH.

Под многобайтными числами будем понимать числа, занимающие два и более байт, т.е. двухбайтные, трехбайтные, четырехбайтные и т.д. числа. Как правило, более старший байт числа располагается в регистре или ячейке с большим номером. Например, следующая запись (R4,R3,R2) говорит о том, что это трехбайтное число (точнее трехбайтный операнд), причем младший (нулевой) байт числа располагается в регистре R2, средний (в данном случае первый) – в регистре R3, а старший (в данном случае второй) – в регистре R4. Таким образом, число АВ56С7Н разместилось бы так: (R2)=С7Н, (R3)=56Н, (R4)=АВН. Следующая запись (25Н,24Н) говорит о том, что это двухбайтное число, причем младший байт располагается в ячейке с адресом 24Н, а старший – в ячейке с адресом 25Н. Еще одна запись ((R0+1), (R0)) говорит о том, что это двухбайтное число, причем младший байт располагается в ячейке, на которую указывает регистр R0, а старший – в следующей ячейке.

Арифметические и логические операции над парами чисел осуществляются последовательно соответственно сначала над младшими (нулевыми) байтами, затем над более старшими (первыми) байтами и т.д. с учетом, при необходимости, связи между байтами. Например, требуется найти сумму двух двухбайтных чисел, причем первое число расположено в (R6,R5), второе – в (R4,R3), а результат необходимо поместить в (R6,R5).

;(R6,R5)ß(R6,R5) + (R4,R3)

MOV A,R5; (A)ß(R5)       сначала складываем

     ADD A,R3; (A)ß(A)+(R3) младшие байты,

MOV R5,A; (R5)ß(A)       а результат в R5, т.е. (R5)ß(R5)+(R3)

MOV A,R6; (A)ß(R6)       затем складываем

     ADDC A,R4;  (A)ß(A)+(R4) старшие байты с учетом (C),

MOV R6,A; (R6)ß(A)       результат в R6, т.е. (R6)ß(R6)+(R4)+(C)

         

Пример с конкретными числами.

  A R3 R4 R5 R6 C
  00H 98H 5EH 8CH 3BH 0
MOV A,R5 8CH - - - - -
ADD A,R3 24H - - - - 1
MOV R5,A - - - 24H - -
MOV A,R6 3BH - - - - 0
ADDC A,R4 9AH - - - - -
MOV R6,A 9AH AAH 98H 24H 9AH 0

     124H=8CH + 98H, причем (C)ß1, (A)ß24H;

9AH=3BH + 5EH + 1, причем (C)ß0, (A)ß9AH.

 

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

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

;(R6,R5)ß(25H,24H) and (R4,R3)

MOV R0,#24H; (R0)ß24H указать на младший байт 1-го операнда

MOV A,@R0; (A)ß((R0))    и записать его значение в A

     ANL A,R3; (A)ß(A)and(R3) логически умножить младшие байты,

MOV R5,A; (R5)ß(A)     а результат в R5

INC R0; (R0)ß(R0)+1 указать на старший байт 1-го операнда

MOV A,@R0; (A)ß((R0))    и записать его значение в A

ANL A,R4; (A)ß(A)and(R4) логически умножить старшие байты,

MOV R6,A; (R6)ß(A)     а результат в R6.

         

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

;(R6,R5)ß(R6,R5) - (R4,R3)

MOV A,R5; (A)ß(R5)       сначала находим

CPL A;                               разность по 2-му способу

     ADD A,R3; (A)ß(A)+(R3) между младшими

CPL A;                                байтами,

MOV R5,A; (R5)ß(A)       а результат в R5, т.е. (R5)ß(R5)-(R3)

MOV A,R6; (A)ß(R6)       затем находим

CPL A;                         разность по 2-му способу

     ADDC A,R4; (A)ß(A)+(R4)  между старшими

     CPL A;                               байтами с учетом C

MOV R6,A; (R6)ß(A)       результат в R6,т.е. (R6)ß(R6)-(R4)-(C)

 

Пример с конкретными числами.

  A R3 R4 R5 R6 C
  00H 98H 5EH 24H 9AH 0
MOV A,R5 24H - - - - -
CPL A DBH - - - - -
ADD A,R3 73H - - - - 1
CPL A 8CH - - - - -
MOV R5,A - - - 8CH - -
MOV A,R6 9AH - - - - -
CPL A 65H - - - - -
ADDC A,R4 C4H - - - - 0
CPL A 3BH - - - - -
MOV R6,A 3BH 98HH 5EH 8CH 3BH 0

     DBH=not(24H) или 11011011B=not(00100100B);

173H=DBH + 98H, причем (C)ß1, (A)ß73H;

8CH=not(73H) или 10001100B=not(01110011B);

65H=not(9AH) или 01100101B=not(10011010B);

C4H=65H + 5EH + 1, причем (C)ß0, (A)ßC4H;

3BH=not(C4H) или 00111011B=not(11000100B).

Сравниваются многобайтные числа также последовательно, начиная с более младших байтов.

;(F0)ß1 при (R6,R5)>=(R4,R3), иначе (F1)ß1

MOV A,R5; (A)ß(R5)       сначала сравниваем

CPL A;                               младшие

     ADD A,R3; (A)ß(A)+(R3) байты

MOV A,R6; (A)ß(R6)       затем сравниваем

CPL A;                         старшие

     ADDC A,R4; (A)ß(A)+(R4)  байты с учетом C

JC M1;        переход при (C)=1, т.е. когда (R6,R5)<(R4,R3)

CLR F0;          иначе, при (C)=0

CPL F0;           (F0)ß1, т.е. когда (R6,R5)>=(R4,R3)

JMP M2;        и обход альтернативного действия

M1: CLR F1;              

     CPL F1;           (F1)ß1, т.е. когда (R6,R5)<(R4,R3)

M2: NOP;               пустой оператор или продолжение программы.

 

Сдвиг многобайтного числа влево через С по схеме

С      n-1 –й байт       n-2 –й байт                               0-й байт

 


осуществляется последовательно, начиная с младшего байта:

    ;сдвиг влево через C (R7,R6,R5)

     CLR C;            (C)ß0   очистка C

     MOV A,R5;              сдвиг

     RLC A;          влево через C

     MOV R5,A;              младшего байта       

     MOV A,R6;              сдвиг

     RLC A;            влево через C

     MOV R6,A;        среднего байта

     MOV A,R7;    сдвиг

     RLC A;                влево через C

     MOV R7,A;        старшего байта

 

     Аналогичный сдвиг вправо через С осуществляется подобным образом, но с использованием команды RRC A, начиная со старшего байта.

     Если при работе с многобайтными числами, впрочем, также как и с однобайтными, требуется сохранить начальное значение аккумулятора, то вместо команды MOV необходимо использовать команду XCH.

Задания к практическому занятию №3:

1)(R7)<--(R3)and(R5); 2) (R2)<--(R6)or(3BH); 3) (3DH)<--(3EH)xor(3FH); 4) сброс 0-го бита R4; 5) установка 7-го бита (2EH); 6) сброс 2,3-го и установка 4,5-го бита R5; 7) сброс младшей тетрады (2ЕH); 8) установка старшей тетрады (2CH); 9) инверсия R7; 10) при (F1)=0 - инверсия B0 (3FH), при(F1)=1 - инверсия B7 (2FH); 11) (R2)<--(R4)-(R3), 1 сп.; 12) (29H)<--(2AH)-(2BH), 2 сп.; 13) (A)<--max (R2),(R6); 14) (R7,R6)<--(R7,R6)+(R4,R3); 15) сдвиг (R4,R3) влево; 16) (R7,R6)<--(R7,R6)-(R3,R2).



Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: