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

How to Convert Decimal to Binary in Assembly Language

我在分析这段将十进制值转换为二进制的代码块时遇到了问题。有人可以帮助解释下面的文字行吗?顺便说一句,这是一个工作代码。我真的很感激帮助,这是为了学习目的。谢谢!

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.....

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

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

指令mov dx, 0000h清除dx,因为进一步向下div cx指令将dx:ax对除以cx,所以如果dx 不为零那么你会得到垃圾。

ax 寄存器以值 08000h 开始,在二进制中是 1 后跟 15 0 并且在循环的每次迭代中它一直是除以 2,所以在每次迭代中,0 的新二进制数字从左侧进入,1 二进制数字向右移动一个位置,0 二进制数字数字从右侧消失。

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

conv:循环是一种非常不正统的方式,根据ax代表的位是否设置,将cx设置为01或在 bx 中清除。这个循环最多循环一次,所以我认为 jmp conv 指令可能会丢失,它可能会掉落到 cont2: 标签。

另请注意,将 2 加载到 cx 然后执行 div cx 是延迟的,您可以 shr ax, 1.