Что делают операции сдвига в сборке Intel 8085? - PullRequest
4 голосов
/ 12 октября 2011

Я пытаюсь объяснить себе следующий код сборки 8085

У меня есть этот код, который запрашивает два числа (с виртуальной клавиатуры в IDE) и отображает их на светодиодах 7 и 8:

.ORG 0000

CALL DATA
MOV C,A
CALL PRNT

CALL DATA
MOV E,A
CALL PRNT

MVI D,00H
MOV L,E
MVI H,00H

MOV A,C
DCR A
JUMP:
DAD D
DCR A
JNZ JUMP

MOV A,L
DAA
JMP IMPR

RET

DATA:
MVI A,00000000B
OUT 00H
IN 00H
RLC
RLC
RLC
RLC
ANI F0H
MOV B,A
MVI A,00000000B
OUT 00H
IN 00H
ANI 0FH
ORA B
RET

IMPR:
MOV B,A

ANI F0H
RLC
RLC
RLC
RLC
CALL NUMZ
OUT 06H
MOV A,B
ANI 0FH
CALL NUMZ
OUT 07H
RET

NUMZ:
CPI 00H
JNZ ONE
MVI A,01110111B
JMP EXIT

ONE:
CPI 01H
JNZ TWO
MVI A,01000100B
JMP EXIT

TWO:
CPI 02H
JNZ THREE
MVI A,00111110B
JMP EXIT

THREE:
CPI 03H
JNZ FOUR
MVI A,01101110B
JMP EXIT

FOUR:
CPI 04H
JNZ FIVE
MVI A,01001101B
JMP EXIT

FIVE:
CPI 05H
JNZ SIX
MVI A,01101011B
JMP EXIT

SIX:
CPI 06H
JNZ SEVEN
MVI A,01111011B
JMP EXIT

SEVEN:
CPI 07H
JNZ EIGHT
MVI A,01000110B
JMP EXIT

EIGHT:
CPI 08H
JNZ NINE
MVI A,01111111B
JMP EXIT

NINE:
CPI 09H
JNZ SAL
MVI A,01001111B
JMP EXIT

EXIT:
RET

Я не включаю PRNT, потому что это не важно для моего вопроса.

Я понимаю .ORG 0000, который является началом программы - это похоже на BEGIN в Паскале.

CALL DATA - это подпрограмма, которая заполняет аккумулятор двоичными нулями и показывает их (?) В порту 0 (00H в шестнадцатеричном формате), затем получает (с виртуальной клавиатуры) число и он поворачивается влево в режиме сдвига.

Мой вопрос: почему?Какой смысл в этом?В чем выгода?Я читал об этом в Википедии, но до сих пор не понимаю.Что он делает в этом коде и зачем он нужен?

1 Ответ

7 голосов
/ 12 октября 2011

Подпрограмма DATA загружает два десятичных символа ASCII и формирует их в двузначное значение BCD .Он сдвигает первый символ влево на 4 бита, сохраняя только биты LS 4, а затем помещает биты LS 4 второго символа в биты LS 4 результата.

В C это будет примерно эквивалентно:

char c = getchar();             // get first ASCII decimal character
char result = (c << 4) & 0xf0;  // shift into MS nybble of result and mask
c = getchar();                  // get second ASCII decimal characters
result = result | (c & 0x0f);   // mask and inset into LS nybble of result
return result;

Обратите внимание, что маскирование всего, кроме nybble LS десятичного знака ASCII дает вам его десятичный эквивалент, например, ASCII '4' = 0x34 => 0x04.


Toпомогите прояснить это. Я нарисовал диаграмму, которая шаг за шагом показывает, что происходит, когда пользователь вводит число «69», то есть ASCII «6», за которым следует ASCII «9», поскольку два символа маскируются и объединяются,BCD представление числа 69:

enter image description here

...