**爲澄清和「更清晰」的代碼進行了編輯。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