我需要编写一个除数程序,该程序使用2个十进制数字(它们可以是正数或负数)并以二进制代码显示答案。
程序正在运行,但只能使用pos或neg数字。当我评论负数时(在NeNegSum
下,我标记了它),它与负数和未评论的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
答案 0 :(得分:1)
您正在使用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