汇编:如何将十六进制输入转换为十进制?

甲虫

我在这个问题上发现了很多问题,但是,我无法运行我的代码。我的程序应采用一个十六进制值,检查它是否是有效的十六进制字符,然后将十六进制值显示为十进制值。如果是小写的十六进制字符,则需要将其转换为大写。所有这些都需要循环。

除了将十六进制转换为十进制之外,我已经完成了所有这些操作。我认为程序中的代码应该将其转换,但无法编译。我将在代码下方列出编译器错误。如果注释了convert:标签中的代码(最后一行“ jmp display”除外),则程序将按预期运行,但显然不会以十进制显示该值。

使用nasme进行编译:“ nasm -fbin getChar.asm -o getChar.com -l getChar.lst”

我正在dosbox中运行该程序。

; This program gets a char from user and prints it out as a decimal 

    org 100h        ; program start point
section .data
    msgIn:  DB  13, 10, "Enter a Hex Digit: $"
    msgOut: DB  13, 10, "Decimal Value: $"
    msgOpt: DB  13, 10, "Enter another?(y or n): $"
    errMsg: DB  13, 10, "Illegal character, Enter 0..9 or A..F: $"
    HNUM:   DB  19H
    NUM:    DB  0
    D:      DB  10h
    H:      DB  16
    CNT:    DB  0

section .text

continue:               ; start of loop
        mov dx, msgIn   ; offset address of message to display
        mov ah, 9       ; print string function
        int 21h

        mov ah, 1       ; keyboard input sub-program
        int 21h         ; read character into al
        mov cl, al

legal:                  ; compare input to see if valid
        cmp cl, 48      ; cl < 0
        jl  end_if      ; yes, error msg
        cmp cl, 70      ; cl > F
        jg  check_case  ; yes, error msg

        jmp prntMsg2    ; print value of input

check_case:             ; check case of input
        cmp cl, 97      ; cl < a
        jl  end_if      ; yes, error msg
        cmp cl, 102     ; cl > f
        jg  end_if      ; yes, error msg

        jmp to_upper    ; need to send to function to convert to upper case
                        ; then pass to prntMsg2

to_upper:
        and al, 223 ; convert to upper case(0DFh)

        jmp prntMsg2

end_if:                 ; error message if invalid input
        mov ah, 9
        mov dx, errMsg  ; print error message
        int 21h

        jmp continue    ; get a new value

prntMsg2:               ; print second message*****
        mov dx, msgOut  ; offset of second message
        mov ah, 9       ; print string function
        int 21h         ; display message

convert:
        mov cx, 00
        mov dx, 00

    L6: mov ax, 00
        mov al, [HNUM]
        div word [D]
        mov [HNUM], al

        mov bx, ax
        mov cl, 0
        mov ax, 1
    L5: 
        cmp cl, 00
        je L7
        mul word [H]
        sub cl, 1
        jmp L5
    L7: 
        mul bh
        add dx, ax
        add word [CNT], 1
        cmp word [HNUM], 0
        jg L6
        mov [NUM], dl

        jmp display

display:                ; display character
        mov dl, al
        mov ah, 2       ; print char function
        int 21h

        mov ah, 9       ; see if user wants to do it again
        mov dx, msgOpt
        int 21h

        mov ah, 1
        int 21h
        mov bl, al
        cmp bl, 'y'     ; bl = y
        jne exitPrg     ; no, end

        jmp continue    ; get a new value

exitPrg:                ; exit program
        mov ah, 4ch     ; exit to DOS function
        int 21h         ; see you later!

上面的代码已被编辑,现在可以编译和运行。但是,它仍然没有正确执行从十六进制到十进制的转换。它只是不显示值,而只是空白。如果输入了字母,甚至是字母af,它也会挂断。数字不会挂断电话,但仍然不会显示值。

现在,我至少可以运行它,但可以修复它,但是,任何指导都值得赞赏。感谢吉恩(Gene)让我起跑。

基因

NASM内存操作数使用方括号表示取消引用。因此,例如,您将需要:

    mov al, [HNUM]
    div byte [D]
    mov [HNUM], al

NASM手册说明这一点。RTFM!

如果没有括号,则将标签视为等于存储位置地址的立即操作数。第一行没有语法错误,但是会导致al加载地址的低字节HNUM不是您想要的。div是一个错误,因为8086没有指令除以立即数。而且这mov是胡说八道,因为您无法写入立即数。

因此,错误消息告诉您出了什么问题。在所引用的行中,操作数与它们的指令不符。

添加

我继续安装了dosbox和NASM。确实,NASM在推断操作数类型方面不如MASM聪明。因此,对于div说明,您需要byte,而不是word上面所示的。我无法理解您的算法。它比必要的更为复杂。这是我的版本:

; This program gets a hex digit from user and prints it out as a decimal 

        org 100h        ; program start point

section .data

msgIn:  DB      13, 10, "Enter a hex digit or q to quit: $"
msgErr: DB      " isn't hex. Must be 0-9, A-F, or a-f.$"
msgOut: DB      " has decimal value $"
buffer: DB      "xxxxx"
endBuf: DB      ".$"
ten:    DB      10

section .text

continue:               ; start user interaction
        mov dx, msgIn   ; offset address of message to display
        mov ah, 9       ; print string function
        int 21h

get_hex_digit:
        mov ah, 1
        int 21h         ; read character into al

check_for_quit:
        cmp al, 'q'     ; handle quit character
        je exit
        cmp al, 'Q'
        je exit

check_for_digit:
        cmp al, '0'     ; handle 0-9
        jl check_for_upper
        cmp al, '9'
        jg check_for_upper
        sub al, '0'     ; convert to numeric value
        jmp print_decimal

check_for_upper:
        cmp al, 'A'     ; handle A-F
        jl check_for_lower
        cmp al, 'F'
        jg check_for_lower
        sub al, 'A'-10  ; convert to numeric value
        jmp print_decimal

check_for_lower:
        cmp al, 'a'     ; handle a-f
        jl handle_digit_error
        cmp al, 'f'
        jg handle_digit_error
        sub al, 'a'-10  ; convert to numeric value

print_decimal:          ; print al contents as decimal 0-255
        mov di, endBuf  ; set buffer pointer to char after digits
next_digit:
        dec di          ; advance buffer pointer to next char
        xor ah, ah      ; clear high byte of ax for division
        div byte [ten]  ; ah = ax % 10, al = ax / 10
        add ah, '0'     ; convert ah to ascii
        mov [di], ah    ; copy to buffer
        or al, al       ; set condition codes with al
        jnz next_digit  ; jump if more digits to print

print_digits:
        mov dx, msgOut  ; offset address of message preamble
        mov ah, 9       ; print string function
        int 21h
        mov dx, di      ; offset address of converted digits
        mov ah, 9       ; print string function
        int 21h

        jmp continue    ; otherwise, get next input

handle_digit_error:
        mov dx, msgErr  ; offset address of message to display
        mov ah, 9       ; print string function
        int 21h
        jmp continue

exit:                   ; exit program
        mov ah, 4ch     ; exit to DOS function
        int 21h         ; see you later!

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何将十进制转换为十六进制字符串的十六进制和XOR

如何将负十六进制转换为十进制

使用AWK,如何将十进制数转换为十六进制数

如何将十进制或十六进制值转换为整数?

如何将很大的十进制字符串转换为十六进制?

如何将十六进制字符串转换为十进制值

Python如何将浮点数十六进制转换为十进制

如何将scala中的十六进制十进制列转换为int

如何将十进制转换为十六进制变量?

如何将 '\x80' 十六进制转换为十进制

如何将十六进制NSData转换为十进制NSData?

Python将十进制转换为十六进制

PHP将十进制转换为十六进制

将十六进制转换为十进制

Dart:将十进制转换为十六进制

lex:将十六进制转换为十进制

使用python将十六进制十进制数字转换为十进制

在javascript中,如何将十进制(带小数点)转换为十六进制字符串

如何将十进制代码点转换为UTF-16十六进制(Java语法)?

如何使用VB将十进制转换为十六进制?

如何在JavaScript中使用LOOP将十六进制转换为十进制

如何使用C语言将十六进制数组转换为十进制

如何使用MIPS将存储的十六进制数组转换为十进制?

如何使用java将十六进制转换为十进制rgb565?

如何手动将 4 个字节的十六进制转换为十进制

将十六进制数组转换为十进制数字Intel 8086汇编语言

如何从十六进制转换为十进制以及从十进制转换为二进制

ShellScript十六进制转换为十进制

从十进制转换为十六进制