Ash*_*hir 4 assembly bitwise-operators bcd 8085
我试图向自己解释以下8085汇编代码
我有这个代码要求两个数字(来自IDE中的虚拟键盘)并在LED 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
Run Code Online (Sandbox Code Playgroud)
我不包括PRNT因为它对我的问题不重要.
我明白.ORG 0000哪个是程序的开始 - 就像BEGIN在Pascal中一样.
CALL DATA是一个子程序,它用二进制零填充累加器并在端口0(十六进制为00H)中显示它们(?),然后它(从虚拟键盘)得到一个数字,然后它在一个位移操作中向左旋转.
我的问题是为什么?这样做有什么意义?有什么好处?我在维基百科上读到过它,但我仍然没有得到它.它在这段代码中做了什么,为什么需要它?
该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;
Run Code Online (Sandbox Code Playgroud)
请注意,屏蔽除ASCII十进制字符的LS nybble之外的所有字符都会给出其十进制等效值,例如ASCII"4"= 0x34 => 0x04.
为了明确这一点,我绘制了一个图表,该图表逐步显示当用户输入数字"69"时发生的情况,即ASCII"6"后跟ASCII"9",因为两个字符被屏蔽并组合到给出数字69的BCD表示:
