如何用汇编语言将十进制转换为二进制
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
设置为0
或1
或在 bx
中清除。这个循环最多循环一次,所以我认为 jmp conv
指令可能会丢失,它可能会掉落到 cont2:
标签。
另请注意,将 2
加载到 cx
然后执行 div cx
是延迟的,您可以 shr ax, 1
.
我在分析这段将十进制值转换为二进制的代码块时遇到了问题。有人可以帮助解释下面的文字行吗?顺便说一句,这是一个工作代码。我真的很感激帮助,这是为了学习目的。谢谢!
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
设置为0
或1
或在 bx
中清除。这个循环最多循环一次,所以我认为 jmp conv
指令可能会丢失,它可能会掉落到 cont2:
标签。
另请注意,将 2
加载到 cx
然后执行 div cx
是延迟的,您可以 shr ax, 1
.