**为澄清和“更清晰”的代码进行了编辑。8086装配(TASM):将ASCII字符值显示为HEX
我试图从键盘(任何字符)接受一个字符,并将它的ASCII值转换为十六进制,然后显示它。
我知道如何从基地10转换为十六进制,但只是为了确保我没有使用不正确的术语:
如果我在为我的ASCII值输入“C”,它的十进制值是63。 63除以16(十六进制是16进制)= 3.9375。稍后保存3的商数。剩余*基数(.9375 * 16)= 15. 15是十六进制字符“F”。
商数除以基数(3/16)= 0.1875。商数为零,所以这是转换的最后一步。剩余*基数(.1875 * 16)= 3
从最后到第一个读取它们(如果考虑堆栈,请先读取“先进先出”),然后将“3F”数字“63”(这是ASCII为“c”)
这是正确的,是吗?
这是很简单的阅读,我希望。我只是从键盘(AL)获取字符,将BX设置为除数(基数为16),然后将AL除以BX,将余数存储在堆栈中,然后在堆栈中循环并尝试显示它。
我觉得我的问题是我的乘法和INT 21H/02H有问题。我不确定是否需要添加30h才能显示该字符或不...
最重要的是,我甚至不确定是否需要在该点(显示)仍然无论如何,因为我还没有想出如何将10-15转换为十六进制的AF。
我试着和我的老师说话,等了30分钟后,他完成了和我班上另一群学生的谈话(关于他班的另一个班级的事情,而不是这个......这让我非常厌烦一点),我得到的最多是“重新开始”。
当问到“使用SHR和SHL怎么办?”正如它向我指出的那样,但我被告知可以不这样做,并且我不能使用这些命令(它们在课堂上没有被覆盖)。
我在做什么错误的任何输入?谢谢!
CHAR2HEX PROC ; Accept a character, print it's ascii value in hex.
MOV DX, OFFSET AskChar ; Display prompt
MOV AH, 09H
INT 21H
MOV AX, 0 ; Clear AX
MOV AH, 07H ; Get keyboard input w/ no echo (AL)
INT 21H
MOV BX, 16 ; Set up the divisor (base 16)
MOV CX, 0 ; Initialize the counter
MOV DX, 0 ; Clear DX
Divide:
; Dividend (what's being divided) in DX/AX pair, Quotient in AX, Remainder in DX.
DIV BX ; Divide (will be word sized).
PUSH AX ; Save DX (the remainder) to stack.
ADD CX, 1 ; Add one to counter
MOV DX, 0 ; Clear Remainder (DX)
CMP AX, 0 ; Compare Quotient (AX) to zero
JNE Divide ; If AX not 0, go to "Divide:"
Multiply:
; Multiply remainder (from stack) by 16 to get hex value.
MOV DX, 0 ; Clear DX
POP AX ; Get remainder from stack into AX.
MUL BX ; Multiply AX * BX. (DX= high order bits, AX = low order bits)
MOV DX, AX
SUB DL, 30h ; ADD 30h to DL
MOV AH, 02h ; 02h to display AH (DL)
INT 21H ; Send to DOS
LOOP Multiply ; If more to do, Multiply again
; LOOP subtracts 1 from CX. If non-zero, loop.
RET
CHAR2HEX ENDP
END START
EDITED **
我终于得到它!我能够让程序返回键盘上按下的ascii字符的十六进制值,但只有当每个余数是0到9时才起作用。它不会显示A到F,而是使用冒号,分号等...
我在网上查看了一个Ascii/Deicmal/Hex图表,并注意到字符0到9是从30h到39h。但字符A(十六进制为10)直到40h才开始。所以我改变了程序,所以如果这个值大于39h,它会在DL上加7h,然后显示它。
CHAR2HEX PROC ; Accept a character, print it's ascii value in hex.
MOV DX, OFFSET AskChar ; Display prompt
MOV AH, 09H
INT 21H
MOV AH, 07H ; Get keyboard input w/ no echo (AL)
INT 21H
MOV CL, AL ; Copy user input (AL) to CL
MOV AX, 0 ; Clear AX (get rid of HO bits)
MOV AL, CL ; Copy user input back into AL
MOV BX, 16 ; Set up the divisor (base 16)
MOV CX, 0 ; Initialize the counter
MOV DX, 0 ; Clear DX
Div2:
; Dividend (what's being divided) in DX/AX pair, Quotient in AX, Remainder in DX.
DIV BX ; Divide (will be word sized).
PUSH DX ; Save DX (the remainder) to stack.
ADD CX, 1 ; Add one to counter
MOV DX, 0 ; Clear Remainder (DX)
CMP AX, 0 ; Compare Quotient (AX) to zero
JNE Div2 ; If AX not 0, go to "Div2:"
getHex2:
MOV DX, 0 ; Clear DX.
POP DX ; Put top of stack into DX.
ADD DL, 30h ; Conv to character.
CMP DL, 39h
JG MoreHex2
HexRet2:
MOV AH, 02h ; 02h to display AH (DL)
INT 21H ; Send to DOS
LOOP getHex2 ; If more to do, getHex2 again
; LOOP subtracts 1 from CX. If non-zero, loop.
JMP Skip2
MoreHex2:
ADD DL, 7h
JMP HexRet2 ; Return to where it left off before adding 7h.
Skip2:
RET
CHAR2HEX ENDP
我可以让我的程序从ASCII转换为十六进制,但只有当每个值为9或更小。 因此,例如,使用“a”作为输入会导致在屏幕上打印“61”。 “b”导致“62”。但如果我输入“K”,结果为“4;”,并且实际上并没有将最后一位数字转换为“A-F”... 这就是我目前无法弄清楚的。这东西很难! – SalarianEngineer 2012-04-25 22:27:20
你想要编写'if(a <= 9)a + = 0x30 else a + = 0x41'(假设a总是在0到15之间)来获得这些数字。这不是很难,但很乏味。 :) – vhallac 2012-04-26 10:01:13