如何在汇编语言中将十进制转换为二进制

时间:2018-03-11 11:11:39

标签: assembly x86 dos masm x86-16

我无法在将十进制值转换为二进制时分析此代码块。有人可以帮助解释下面的文字行吗?顺便说一句,这是一个有效的代码。我非常感谢你的帮助,这是为了学习目的。谢谢你!

calc :
    mul multiplier
    mov bl, byte ptr [si]
    mov bh, 00h
    add ax, bx
    inc si
    loop calc

    mov si, offset buf4 + 2
    mov bx, ax
    mov dx, 0000h
    mov ax, 8000h
convert :
    mov cx, 0000h
conv :
    cmp bx, ax
    jb cont3
    sub bx, ax
    inc cx
    jmp conv
cont3 :
    add cl, 30h
    mov byte ptr [si], cl
    inc si
    mov cx, 0002h
    div cx
    cmp ax, 0000h
    jnz convert

    mov byte ptr [si], '$'
    prnstr buf3
    prnstr buf4+2
stop :
    mov ax, 4c00h
    int 21h

代码的第一部分没有问题(接受用户输入并检查它是否是有效的十进制数)。我已经添加了一些注释..代码的前半部分如下所示:

prnstr macro msg     ;acts like a function to print string
    mov ah, 09h
    lea dx, msg
    int 21h
    endm

data segment
    buf1 db "Enter a decimal number : $"
    buf2 db 0ah, "Invalid Decimal Number...$"
    buf3 db 0ah, "Equivalent Binary number is : $"
    buf4 db 6
         db 0
         db 6 dup(0)
    multiplier db 0ah
data ends

code segment
    assume cs:code, ds:data
    start :
    mov ax,@data
    mov ds,ax
    mov es, ax   

    prnstr buf1         ;Display

    mov ah, 0ah         ;Get line function
    lea dx, buf4        ;adress of input buffer
    int 21h

    mov si, offset buf1 + 2 ;Load pointer to beginning of structure
    mov cl, byte ptr [si-1] ;determine end of loop?
    mov ch, 00h
    subtract :
    mov al, byte ptr [si]   ;Load 1 byte of buf1 to cl
    cmp al, 30h             ;check if not below 0
    jnb cont1

    jmp stop
 cont1 :
    cmp al, 3ah         ;check if not above 9
    jb cont2
    prnstr buf2         ;Display
    jmp stop
 cont2 :
    sub al, 30h             ;convert ASCII to Decimal number
    mov byte ptr [si], al   ;place bcd form back to pointed character
    prnstr buf2             ;Display
    inc si                  ;next character
    loop subtract           ;repeat until end of string
    mov si, offset buf1 + 2 ;Load pointer to beginning of structure
    mov cl, byte ptr [si-1] ;reset to determine end of loop using si
    mov ch, 00h
    mov ax, 0000h           ;reset ax to 0

    ;...CONTINUE TO calc.....

1 个答案:

答案 0 :(得分:2)

calc:循环保持乘以10并累加,因此它似乎计算以十进制输入的数字的实际值。 (它将您输入的字符串(例如“42”)转换为数字42。)

其余代码将计算的数字转换为二进制。至少可以说,它是以一种非正统的方式写成的。

指令mov dx, 0000h会清除dx,因为div cx指令的下方会将dx:ax对划分为cx,所以如果dx是不是零,那么你会得到垃圾。

ax寄存器以值08000h开头,其中二进制值为1,后跟15 0 s,并且在循环的每次迭代中,它始终被除以2,所以在每次迭代时,0的新二进制数字从左侧进入,1二进制数字向右移动一个位置,0二进制数字下降从右边出来。

ax对零的检查将在16次迭代后1二进制数字丢失时停止循环,ax全部为零。

conv:循环是将cx设置为01的一种非常不正统的方式,具体取决于ax表示的位是设置还是已清除在bx。这个循环最多循环一次,所以我认为jmp conv指令可能会丢失,它可能会落到cont2:标签。

另请注意,将2加载到cx然后执行div cx会被延迟,您只能shr ax, 1