** 为澄清和“更清洁”的代码而编辑。
我正在尝试从键盘接受一个字符(任何字符)并将其 ASCII 值转换为十六进制,然后显示它。
我知道如何从基数 10 转换为十六进制,但只是为了确保我没有使用不正确的术语:
如果我输入“c”作为我的 ASCII 值,它的十进制值为 63。63 除以 16(十六进制为 16 进制)= 3.9375。保存 3 的商以备后用。余数 * 基数 (.9375 * 16) = 15。15 是十六进制字符“F”。
商除以基数 (3 / 16) = 0.1875。商为零,所以这是转换的最后一步。余数 * 基数 (.1875 * 16) = 3
从后到前读取它们(“先进后出”,如果考虑堆栈),我得到“3F”作为十进制数“63”的十六进制值(这是“c”的ASCII)
这是正确的,是吗?
我希望它读起来很简单。我只是从键盘(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
已编辑**
我终于明白了!我能够让程序返回在键盘上按下的 ascii 字符的十六进制值,但它仅在每个余数为 0 到 9 时才有效。它不会显示 A 到 F,而是使用冒号,分号等...
我在网上查看了一个 Ascii/Deicmal/Hex 图表,注意到字符 0 到 9 是 30h 到 39h。但是字符 A(十六进制 10)直到 40 小时才开始。所以我改变了程序,如果该值大于 39h,它将 7h 添加到 DL 并显示它。
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