为什么我会溢出? (NASM 汇编器)
Why am I getting overflow? (NASM Assembler)
为了这个程序的目的,我必须编写一个程序来计算圆锥体的体积,该圆锥体的体积为 22/21*(r^2)*h。
所以我开发的这段代码适用于任何变量,这些变量在将变量相乘后不会导致 EDX 寄存器被填充。我不能将寄存器或 "OR" 一起移位,也不能使用跳转或 cmp 语句。我还必须为高度和宽度变量使用 8 位寄存器,为 radius^2 和 radius^2*height 计算使用 16 位寄存器,然后用 32 位寄存器完成最后的除法计算。看一看。我不知道为什么它会溢出到EDX中,我也不知道如何纠正它...
.data
radius WORD ? ;var for radius
height WORD ? ;var for height
numerator WORD 22 ;Making a variable for numerator
denominator DWORD 21 ;Making a variable for denominator
volume DWORD ? ;Making a variable to store volume main
decimal DWORD ? ;Making a variable to store volume remainder
prompt BYTE "Enter the radius: ",0 ;val for radius prompt
promp2 BYTE "Enter the height: ",0 ;val for height prompt
result BYTE "The volume of the cone is: ", 0 ;val for printing volume
decim BYTE ".", 0 ;val for decimal place
;volume of cone is 1/3(pi(r^2)h) or 22/21(r^2)h
.code
main PROC
mov edx,OFFSET promp2 ;move prompt into edx for printing
call WriteString ;ask user for height
mov eax,0
mov edx,0
mov ecx,0
mov ebx,0 ;move zero into all main registers
call ReadDec ;reading the height
mov bl,al ;move height into storage
mov edx,OFFSET prompt ;move promp2 into edx for printing
mov eax,0 ;re-zero eax
call WriteString ;ask user for radius
call ReadDec
mul al ;obtain r^2
mul bl ;multiply r^2 by height
mov edx,0 ;zero out edx
mov dx,numerator ;move numerator into dx
mul dx ;multiply r^2*h by 22
mov ebx,denominator ;move 21 into ebx to divide
div ebx ;divide by 21 to get total volume
mov volume,eax ;move volume into volume variable
mov decimal,edx ;move decimal remainder into decimal variable
mov edx,OFFSET result ;prepare string result for printing
call WriteString ;print result string
mov eax,volume ;move volume into eax to print
call WriteDec ;print volume
mov edx,OFFSET decim ;move dec into print register
call WriteString ;print decimal
mov eax,decimal ;move decimal remainder into eax to print
call WriteDec ;print decimal value
call CRLF ;carriage return and new line
call WaitMsg ;pause output
exit
main ENDP
也许我可以为中间算法做不同的寄存器,但我不知道如何在当前的 8-8-16-16-32 要求下完成。如果有人可以帮助我提供一个有效的解决方案并解释它为什么有效,也许可以逐步解决它,这样我就能理解为什么我的不适用于更大的整数(大多数超过 20 的整数不起作用),那将是惊人的。提前感谢您能给我的任何帮助!
让我们来看看整个计算:
mul al ;obtain r^2
这个 mul al
在 AX
寄存器中留下一个结果。所以你必须在下一行使用单词 multiply 否则你会丢失 r^2.
的一部分值
mov bh, 0
mul bx ;multiply r^2 by height
现在结果在 DX:AX
。要将其乘以 22,您可以通过堆栈将其移动到 32 位寄存器 EAX
。
push dx
push ax
pop eax
movzx edx, numerator ;Why is this defined a word?
mul edx
这次结果在EDX:EAX
,准备进行最后的划分
div denominator
最后将EAX
中的商和EDX
中的余数移动到各自的变量中。
mov volume, eax ;move volume into volume variable
mov decimal, edx
为了这个程序的目的,我必须编写一个程序来计算圆锥体的体积,该圆锥体的体积为 22/21*(r^2)*h。
所以我开发的这段代码适用于任何变量,这些变量在将变量相乘后不会导致 EDX 寄存器被填充。我不能将寄存器或 "OR" 一起移位,也不能使用跳转或 cmp 语句。我还必须为高度和宽度变量使用 8 位寄存器,为 radius^2 和 radius^2*height 计算使用 16 位寄存器,然后用 32 位寄存器完成最后的除法计算。看一看。我不知道为什么它会溢出到EDX中,我也不知道如何纠正它...
.data
radius WORD ? ;var for radius
height WORD ? ;var for height
numerator WORD 22 ;Making a variable for numerator
denominator DWORD 21 ;Making a variable for denominator
volume DWORD ? ;Making a variable to store volume main
decimal DWORD ? ;Making a variable to store volume remainder
prompt BYTE "Enter the radius: ",0 ;val for radius prompt
promp2 BYTE "Enter the height: ",0 ;val for height prompt
result BYTE "The volume of the cone is: ", 0 ;val for printing volume
decim BYTE ".", 0 ;val for decimal place
;volume of cone is 1/3(pi(r^2)h) or 22/21(r^2)h
.code
main PROC
mov edx,OFFSET promp2 ;move prompt into edx for printing
call WriteString ;ask user for height
mov eax,0
mov edx,0
mov ecx,0
mov ebx,0 ;move zero into all main registers
call ReadDec ;reading the height
mov bl,al ;move height into storage
mov edx,OFFSET prompt ;move promp2 into edx for printing
mov eax,0 ;re-zero eax
call WriteString ;ask user for radius
call ReadDec
mul al ;obtain r^2
mul bl ;multiply r^2 by height
mov edx,0 ;zero out edx
mov dx,numerator ;move numerator into dx
mul dx ;multiply r^2*h by 22
mov ebx,denominator ;move 21 into ebx to divide
div ebx ;divide by 21 to get total volume
mov volume,eax ;move volume into volume variable
mov decimal,edx ;move decimal remainder into decimal variable
mov edx,OFFSET result ;prepare string result for printing
call WriteString ;print result string
mov eax,volume ;move volume into eax to print
call WriteDec ;print volume
mov edx,OFFSET decim ;move dec into print register
call WriteString ;print decimal
mov eax,decimal ;move decimal remainder into eax to print
call WriteDec ;print decimal value
call CRLF ;carriage return and new line
call WaitMsg ;pause output
exit
main ENDP
也许我可以为中间算法做不同的寄存器,但我不知道如何在当前的 8-8-16-16-32 要求下完成。如果有人可以帮助我提供一个有效的解决方案并解释它为什么有效,也许可以逐步解决它,这样我就能理解为什么我的不适用于更大的整数(大多数超过 20 的整数不起作用),那将是惊人的。提前感谢您能给我的任何帮助!
让我们来看看整个计算:
mul al ;obtain r^2
这个 mul al
在 AX
寄存器中留下一个结果。所以你必须在下一行使用单词 multiply 否则你会丢失 r^2.
mov bh, 0
mul bx ;multiply r^2 by height
现在结果在 DX:AX
。要将其乘以 22,您可以通过堆栈将其移动到 32 位寄存器 EAX
。
push dx
push ax
pop eax
movzx edx, numerator ;Why is this defined a word?
mul edx
这次结果在EDX:EAX
,准备进行最后的划分
div denominator
最后将EAX
中的商和EDX
中的余数移动到各自的变量中。
mov volume, eax ;move volume into volume variable
mov decimal, edx