4

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 ?

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Ashir
  • 511
  • 2
  • 8
  • 24

1 Answers1

7

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

Paul R
  • 208,748
  • 37
  • 389
  • 560
  • Paul, that don't ask my question... why?, what's the point in doin so?, what's the benefit??? I have read about it in wikipedia but I still don't get it. What it does in this code and why it's need it. – Ashir Oct 12 '11 at 08:50
  • Which part of the above answer didn't you understand ? The 4 `RLC` instructions are equivalent to `<< 4` in C - is that what was puzzling you ? – Paul R Oct 12 '11 at 08:50
  • Why you need to rotate them? why?, what's the point in doin so?, what's the benefit??? What it does in this code and why it's need it... – Ashir Oct 12 '11 at 08:59
  • @Ashir: "why?" is a question for you. You should know better what exactly the program is for and what data it receives from port 0. At this moment I can't answer this "why?" question because I don't have that information and the presented code doesn't look sufficient to me to figure out what's happening in it and why. – Alexey Frunze Oct 12 '11 at 09:12
  • 1
    @Ashir: to further answer the question "why": your program needs to get two 4 bit values into an an 8 bit register - how is it going to do that ? It needs to move one of the 4 bit values up into the top 4 bits of the 8 bit value and then put the other 4 bit value into the low 4 bits. In order to achieve this it needs to shift one of the values left by 4 bits and mask both of them appropriately. Maybe a diagram would help ? – Paul R Oct 12 '11 at 09:31
  • @Alex: I edited the question. Added the full code. The program it's supposed to get 2 numbers by the virtual keyboard on the IDE and then show them on leds 7 and 8 – Ashir Oct 12 '11 at 09:31
  • @Paul R: Hummm, thats a better aswer Paul. Now if I understand you right, everytime I get a 4 bit value to be stored in a 8 bit register I need to rotate it... it's so much like transforming it from 4 bit to 8 bit (tell me if I'm wrong). Now I wonder, it's indistinct using RLC or using RRC? – Ashir Oct 12 '11 at 09:41
  • @Ashir: yes, but you would need 5 RRCs because of the carry flag, so it makes more sense to use 4 RLCs. – Paul R Oct 12 '11 at 09:45
  • @PaulR: Ok, to be completely sure I understand you. 9 in 4 bit binary it's 1001 so 9 in 8 bit it's 1001 0000, right?. What happend if you use 2 digits, like 92 (0101 1100), you still need rotation? – Ashir Oct 12 '11 at 09:58
  • @Ashir: OK - let's take a simple concrete example - the user enters '6' and then '9'. The first '6' = 0x36 gets masked to 0x06, then shifted left 4 bits to become 0x60. The '9' = 0x39 get masked to 0x09 and then ORed with 0x60 to give you 0x69, which is the value 69 expressed in BCD. Is that clear now ? – Paul R Oct 12 '11 at 11:42
  • OK - here it is in binary: The user enters '6' and then '9'. The first '6' = 0x36 = 00110110 gets masked to 0x06 = 00000110, then shifted left 4 bits to become 0x60 = 01100000. The '9' = 0x39 = 00111001 gets masked to 0x09 = 00001001 and then ORed with 0x60 = 01100000 to give you 01101001, which is the value 69 expressed in BCD. Is that clear now ? – Paul R Oct 14 '11 at 06:43
  • Hum no, I don't get it, but it's because you are using a diferent example for my question. If I get you bit shifting is needed when you have a 4 bit data and need to store it in a 8 bit register, so if you have 9 in 4 bit binary it's represented as 1001, but in 8 bit is represented as 1001 0000(after shifting). But, what happend if you use 2 digits?, let's say 92 I.E., in binary that's 0101 1100. As all 8 bits are used I'm guessing that 92 it's a 8 bit number, form by 2 4 bits digits... You need to bit shift it to store it in a 8 bit register?, my bet it's yes because upper and lower bit thing – Ashir Oct 14 '11 at 08:05
  • 1
    OK - I suggest that instead of just deciding that you "don't get it" you should perhaps spend a little more time working through the example - write notes on paper and draw some diagrams of the 8 bit result register as you go. All that you need to know is explained above - you just need a little patience and persistence to understand it. Good luck ! – Paul R Oct 14 '11 at 08:09
  • See diagram added to answer above. – Paul R Oct 14 '11 at 08:33
  • 1
    Hell yeah, they should have a badge for "xtreme patience" if you commented your own answer more than 5 times. – jishi Oct 14 '11 at 08:42
  • 1
    I second the +1 for `xtreme patience` :-) And Paul, if he still doesn't get it, its definitely not your fault. – Gunther Piez Sep 14 '12 at 07:22