What do bitshift operations in Intel 8085 assembly do?

1.4k views Asked by At

I am trying to explain to myself the following 8085 assembly code

I have this code that asks for two numbers (from a virtual keyboard within the IDE) and displays them on LEDs 7 and 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

I'm not including PRNT because it's not important for my question.

I understand .ORG 0000 which is the start of the program - it's like BEGIN in Pascal.

CALL DATA is a subroutine which fills the Accumulator with binary zeros and shows them (?) in port 0 (00H in hex), then it gets (from the virtual keyboard) a number and then it's rotated left in a bit shift operation.

My question is why ? What's the point in doing so ? What's the benefit ? I have read about it in Wikipedia but I still don't get it. What does it do in this code and why is it needed ?

1

There are 1 answers

16
Paul R On

The DATA subroutine is loading two ASCII decimal characters and forming them into a two digit BCD value. It shifts the first character left by 4 bits, keeping only the LS 4 bits and then puts the LS 4 bits of the second character into the LS 4 bits of the result.

In C this would be roughly equivalent to:

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;

Note that masking all but the LS nybble of an ASCII decimal character gives you its decimal equivalent, e.g. ASCII '4' = 0x34 => 0x04.


To help make this clear I have drawn a diagram which shows step-by-step what happens when the user enters the number "69", i.e. ASCII '6' followed by ASCII '9', as the two characters are masked and combined to give a BCD representation of the number 69:

enter image description here