Что делают операции битового сдвига в сборке Intel 8085?

Я пытаюсь объяснить себе следующий ассемблерный код 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 в шестнадцатеричном формате), затем получает (с виртуальной клавиатуры) число и затем поворачивает влево в битовая операция сдвига.

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


person Ashir    schedule 12.10.2011    source источник


Ответы (1)


Подпрограмма 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;

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


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

введите описание изображения здесь

person Paul R    schedule 12.10.2011
comment
Пол, не задавай мне вопроса ... почему? Какой в ​​этом смысл? Какая польза ??? Я читал об этом в Википедии, но до сих пор не понимаю. Что он делает в этом коде и зачем это нужно. - person Ashir; 12.10.2011
comment
Какую часть ответа вы не поняли? 4 RLC инструкции эквивалентны << 4 в C - это то, что вас озадачило? - person Paul R; 12.10.2011
comment
Зачем нужно их вращать? зачем ?, какой в ​​этом смысл ?, какая польза ??? Что он делает в этом коде и зачем это нужно ... - person Ashir; 12.10.2011
comment
@ Ашир: почему? это вопрос к вам. Вы должны лучше знать, для чего именно предназначена программа и какие данные она получает с порта 0. На данный момент я не могу ответить, почему? вопрос, потому что у меня нет этой информации, и представленный код мне кажется недостаточным, чтобы понять, что в нем происходит и почему. - person Alexey Frunze; 12.10.2011
comment
@Ashir: чтобы подробнее ответить на вопрос, почему: вашей программе нужно получить два 4-битных значения в 8-битный регистр - как она это сделает? Ему необходимо переместить одно из 4-битных значений в верхние 4 бита 8-битного значения, а затем поместить другое 4-битное значение в младшие 4 бита. Для этого необходимо сдвинуть одно из значений на 4 бита влево и соответствующим образом замаскировать их оба. Может, схема поможет? - person Paul R; 12.10.2011
comment
@Alex: Я редактировал вопрос. Добавил полный код. Программа должна получить 2 числа с виртуальной клавиатуры в среде IDE, а затем показать их на светодиодах 7 и 8. - person Ashir; 12.10.2011
comment
@Paul R: Хммм, это лучший ответ, Пол. Теперь, если я вас правильно понимаю, каждый раз, когда я получаю 4-битное значение для хранения в 8-битном регистре, мне нужно его повернуть ... это так похоже на преобразование его из 4-битного в 8-битное (скажите мне, если я ошибаюсь ). Вот интересно, нечетко при использовании RLC или при использовании RRC? - person Ashir; 12.10.2011
comment
@Ashir: да, но вам понадобится 5 RRC из-за флага переноса, поэтому имеет смысл использовать 4 RLC. - person Paul R; 12.10.2011
comment
@PaulR: Хорошо, чтобы быть полностью уверенным, что я вас понимаю. 9 в 4-битном двоичном формате - это 1001, поэтому 9 в 8-битном формате - это 1001 0000, не так ли? Что произойдет, если вы используете 2 цифры, например 92 (0101 1100), вам все равно понадобится ротация? - person Ashir; 12.10.2011
comment
@Ashir: Хорошо, давайте возьмем простой конкретный пример - пользователь вводит «6», а затем «9». Первый '6' = 0x36 маскируется до 0x06, затем сдвигается влево на 4 бита, чтобы стать 0x60. '9' = 0x39 маскируется до 0x09, а затем объединяется с 0x60, чтобы получить 0x69, что является значением 69, выраженным в BCD. Теперь это ясно? - person Paul R; 12.10.2011
comment
ОК - здесь он в двоичном формате: пользователь вводит «6», а затем «9». Первый '6' = 0x36 = 00110110 маскируется до 0x06 = 00000110, затем смещается влево на 4 бита, чтобы стать 0x60 = 01100000. '9' = 0x39 = 00111001 маскируется до 0x09 = 00001001, а затем объединяется с 0x60 = 01100000, чтобы дать you 01101001, то есть значение 69, выраженное в двоично-десятичном формате. Теперь это ясно? - person Paul R; 14.10.2011
comment
Хм, нет, я не понимаю, но это потому, что вы используете другой пример для моего вопроса. Если я понимаю, что сдвиг битов необходим, когда у вас есть 4-битные данные и вам нужно хранить их в 8-битном регистре, поэтому, если у вас 9 в 4-битном двоичном формате, он представлен как 1001, а в 8-битном представлен как 1001 0000 ( после переключения). Но что произойдет, если вы используете 2 цифры?, Скажем, 92 IE в двоичном формате, это 0101 1100. Поскольку используются все 8 бит, я предполагаю, что 92 это 8-битное число, состоящее из 2 4-битных цифр ... Вы нужно сдвинуть бит, чтобы сохранить его в 8-битном регистре? Могу поспорить, что да, потому что верхний и нижний бит - person Ashir; 14.10.2011
comment
Хорошо - я предлагаю, чтобы вместо того, чтобы просто решить, что вы этого не понимаете, вам, возможно, следует потратить немного больше времени на проработку примера - написать заметки на бумаге и по ходу нарисовать несколько диаграмм 8-битного регистра результатов. Все, что вам нужно знать, объяснено выше - вам просто нужно немного терпения и настойчивости, чтобы понять это. Удачи ! - person Paul R; 14.10.2011
comment
См. Диаграмму, добавленную к ответу выше. - person Paul R; 14.10.2011
comment
Черт возьми, у них должен быть значок экстремального терпения, если вы прокомментировали свой ответ более 5 раз. - person jishi; 14.10.2011
comment
Я ставлю +1 за xtreme patience :-) И Пол, если он все еще не получает его, это определенно не твоя вина. - person Gunther Piez; 14.09.2012