我需要编写一个分割程序,它取两个十进制数字(它们可以是正数或负数)并以二进制代码显示答案。
程序正在运行但只有pos或neg数字。当我评论neg(在NeNegSum
下,我标记它)时,它与neg数字一起使用,并且在没有评论时使用pos。我需要做什么,让它与所有数字一起工作?
include 'win32ax.inc'
include 'input.inc'
.data
num1 dd 0
num2 dd 0
mes rb 100h
Flag db 0
.code
start:
input_dialog
or eax, eax
jz exit
mov esi, eax
call ASCIIToNum
cmp [Flag],1
jne .NeNeg
;neg eax
mov [Flag],0
.NeNeg:
mov [num1], eax
input_dialog
;mov ecx, 3
or eax, eax
jz exit
mov esi, eax
call ASCIIToNum
cmp [Flag],1
jne .NeNeg2
;neg eax
mov [Flag],0
.NeNeg2:
mov [num2], eax
div [num1]
mov ebx,2
lea esi, [mes+50]
cmp eax,0
jl .NeNegSumm
neg eax
mov [Flag],0
.NeNegSumm:
;neg eax ;<———this neg
call NumToASCII
cmp [Flag],1
jne .Cout
dec esi
mov byte [esi],'-'
.Cout:
invoke MessageBox, HWND_DESKTOP, esi, "Div is:", MB_OK
exit:
invoke ExitProcess,0
.end start
.input_resources
proc ASCIIToNum
;local sum2 dd 0
push ebx ecx
xor eax,eax
xor ebx,ebx
mov ecx, 10
jmp .next
.next1:
mov [Flag],1
;inc esi
.next:
mov bl, [esi]
inc esi
cmp bl,'-'
je .next1
cmp bl, ''
or bl,bl
jz .done
sub bl, 30h
mul ecx
add eax,ebx
jmp .next
.done:
pop ecx ebx
ret
endp
proc NumToASCII
;.sum2 rb 100
push ecx edx
mov byte [esi], 0
mov ecx,2
.divloop:
mov edx, 0
div ecx
add dl, 30h
dec esi
mov [esi], dl
or eax, eax
jnz .divloop
pop edx ecx
ret
endp
您正在使用DIV
指令来计算num2 / num1
。 DIV
用于划分无符号数。如果您需要划分有符号数(正数和负数),请使用IDIV
指令。
由于IDIV [num1]
实际上执行EDX:EAX / [num1]
,所以不要忘记事先签署延长红利。 (cdq
签名 - 将EAX扩展到EDX:EAX,即将EDX的所有位设置为EAX的符号位。)
此除法的商已经是有符号数。要决定输出“ - ”字符,只需查看EAX
中数字的符号即可。
附加评论:
。将符号相关指令移动到ASCIIToNum转换例程更有意义。
。转换为二进制表示不应使用除以2(非常低效)。只需向右移动即可轻松完成此操作。
。您可以编写此代码而无需单独的Flag变量。而是保存和恢复处理器标志。
include 'win32ax.inc'
include 'input.inc'
.data
num1 dd 0
num2 dd 0
mes rb 100h
.code
start:
input_dialog
test eax, eax
jz exit
mov esi, eax
call ASCIIToNum
mov [num1], eax
input_dialog
test eax, eax
jz exit
mov esi, eax
call ASCIIToNum
mov [num2], eax
CDQ ;Sign-extend EAX into EDX:EAX
IDIV [num1] ;Signed division of EDX:EAX by [num1]
lea esi, [mes+50]
test eax, eax
pushf
jns .Convert ;Quotient was positive, no NEG needed
neg eax
.Convert:
call NumToASCII
popf
jns .Cout ;Quotient was positive, no '-' needed
dec esi
mov byte [esi], '-'
.Cout:
invoke MessageBox, HWND_DESKTOP, esi, "Div is:", MB_OK
exit:
invoke ExitProcess,0
.end start
.input_resources
; Input: ESI
; Output: EAX
proc ASCIIToNum
push ebx esi
xor eax, eax
movzx ebx, byte [esi]
cmp bl, '-'
pushf
sete bl ;Number is positive, no unary '-' to skip
add esi, ebx
.next:
mov bl, [esi]
inc esi
test bl, bl
jz .done
sub bl, 30h
imul eax, 10
add eax, ebx
jmp .next
.done:
popf
jne .pos ;Number is positive, no NEG needed
neg eax
.pos:
pop esi ebx
ret
endp
; Input: EAX
; Output: ESI, EAX=0
proc NumToASCII
push edx
mov byte [esi], 0
.divloop:
mov dl, '0'
shr eax, 1
adc dl, 0
dec esi
mov [esi], dl
test eax, eax
jnz .divloop
pop edx
ret
endp