大会:如何转换输入十六进制到十进制? [英] Assembly: How to convert hex input to decimal?

查看:400
本文介绍了大会:如何转换输入十六进制到十进制?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我发现有很多问题,但是,我一直没能得到我的code运行。我的程序应该采取一个十六进制值,检查,看它是否是一个有效的十六进制字符,然后显示十六进制值作为一个十进制值。如果它是一个小写十六进制字符,则需要被转换为大写。所有这需要在一个循环

I have found many questions on this issue, however, I have not been able to get my code to run. My program should take a hex value, check to see if it is a valid hex character, then display the hex value as a decimal value. If it is a lower case hex character then it needs to be converted to upper case. All this needs to be in a loop.

我有这一切,除了转换十六进制到十进制完成。我在节目中,我认为应该把它转换了code,但它不会编译。我将列出以下code编译器错误。如果在标签转换code:被注释掉了(除了最后一行,JMP显示),则程序会运行,因为它应该,但显然不会显示该值作为一个十进制

I have all of this done except for converting the hex to decimal. I have the code in the program I think should convert it, but it will not compile. I will list the compiler errors below the code. If the code in the label convert: is commented out(except for the last line, "jmp display") then the program will run as it should, but obviously will not show the value as a decimal.

与nasme编译:NASM -fbin getchar.asm中-o getChar.com -l getChar.lst

Compiling with nasme: "nasm -fbin getChar.asm -o getChar.com -l getChar.lst"

我运行在DOSBox中的程序。

I am running the program in 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!

在code以上已被编辑,现在编译和运行。然而,它仍然不能从十六进制执行转换到正确十进制。它根本不显示数值,只是空白。它也将挂断如果输入一个字母,甚至一个字母A-F。许多不挂起来,但仍然没有显示的值。

The code above has been edited and now compiles and runs. However, it is still not doing the conversion from hex to decimal correctly. It simply doesn't display a value, just blank. It will also hang up if a letter is entered, even a letter a-f. A number does not hang it up, but still a value is not displayed.

现在我有它运行至少我可以修复它​​工作,但是,任何指导AP preciated。由于基因的让我启动和运行。

Now that I have it running at least I can work on fixing it, however, any guidance is appreciated. Thanks Gene for getting me up and running.

推荐答案

NASM内存操作数使用方括号来表示提领。因此,例如,你会想:

NASM memory operands use square brackets to denote dereferencing. So for example you will want:

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

借助 NASM手册解释这一点。 RTFM!

The NASM Manual explains this. RTFM!

没有括号,标签是作为立即操作数等于存储器单元的地址进行处理。第一行是没有语法错误,但导致加载与 HNUM 地址的低字节。不是你想要的。在 DIV 是一个错误,因为8086没有指令通过即时数量来划分。和 MOV 是无稽之谈,因为你不能写一个直接的价值。

Without the brackets, the labels are treated as immediate operands equal to the address of the memory location. The first line is no syntax error, but causes al to be loaded with the low byte of the address of HNUM. Not what you wanted. The div is an error because 8086 has no instruction to divide by an immediate quantity. And the mov is nonsense because you can't write to an immediate value.

因此​​,错误信息,告诉你什么是错的。在引用的线条,操作数不与他们的指导相称。

So the error messages are telling you what's wrong. In the lines referenced, the operands do not comport with their instructions.

加入

我继续安装DOSBox中和NASM。事实上NASM是不是很MASM智能推断左右操作数类型。所以对于 DIV 指令需要字节,(未)像现在上面反映。我不能神交你的算法。它比必要更复杂。这里是我的版本:

I went ahead and installed dosbox and NASM. Indeed NASM is not quite as smart as MASM about inferring operand types. So for the div instruction you need byte, (not word) as now reflected above. I could not grok your algorithm. It's more complicated than necessary. Here is my version:

; 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!

这篇关于大会:如何转换输入十六进制到十进制?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆