我无法在将十进制值转换为二进制时分析此代码块。有人可以帮助解释下面的文字行吗?顺便说一句,这是一个有效的代码。我非常感谢你的帮助,这是为了学习目的。谢谢你!
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.....
答案 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
设置为0
或1
的一种非常不正统的方式,具体取决于ax
表示的位是设置还是已清除在bx
。这个循环最多循环一次,所以我认为jmp conv
指令可能会丢失,它可能会落到cont2:
标签。
另请注意,将2
加载到cx
然后执行div cx
会被延迟,您只能shr ax, 1
。