我写了一个计算子弹量的程序。对于半径为1.2,我应该得到7(向下舍入7.23)。相反,我得到9。
我已经逐行查看了程序,但我无法看到我犯了哪些错误。我的代码如下所示:
section .text
global _start
_start:
FINIT
FLD dword [radius] ;; st0 - radius
FLDPI ;; st0 - pi, st1 - radius
xor eax,eax
mov eax,4
mov [operator],eax
FLD dword [operator] ;; st0 - operator, st1 - pi, st2 - radius
mov eax,3
mov [operator2],eax
FLD dword [operator2] ;; st0- operator2, st1- operator, st2- pi, st3- radius
FXCH st1 ;; st0- operator, st1- operator2, st2- pi, st3- radius
FDIV st0,st1 ;; st0- operator/operator2 = 4/3, st1- operator2, st2- pi, st3- promien
FXCH st3 ;; radius, operator2, pi, operator/operator2
FMUL st0,st0 ;; st0- radius^2
FMUL st0,st0 ;; st0- radius^3
FMUL st0,st3 ;; st0- radius^3 * 4/3
FMUL st0,st2 ;; st0- radius^3 * 4/3 * pi
FISTP dword [result]
xor eax,eax
mov eax,[result]
add eax,48
mov [result],eax
mov eax,4
mov ebx,1
mov ecx,result
mov edx,4
int 80h
mov eax,1
int 80h
section .data
radius dd 1.2
operator dd 0
operator2 dd 0
result dd 0
答案 0 :(得分:2)
在这里,您尝试加载几个整数,就像它们是32位浮点值一样:
mov eax,4
mov [operator],eax
FLD dword [operator] ;; st0 - operator, st1 - pi, st2 - promien
mov eax,3
mov [operator2],eax
FLD dword [operator2] ;; st0- operator2, st1- operator, st2- pi, st3- promien
要加载32位整数并将其转换为浮点数,您应该使用FILD dword [foo]
。
来自英特尔软件开发人员手册:
FILD-Load Integer
将有符号整数源操作数转换为双扩展精度浮点格式并推送 值到FPU寄存器堆栈上。源操作数可以是字,双字或四字整数。它已加载 没有舍入错误。保留源操作数的符号。
答案 1 :(得分:1)
除了Michael提到的问题之外,您似乎使用了半径 4 而不是radius 3
FMUL st0,st0 ;; st0-半径^ 2
FMUL st0,st0 ;; st0- radius ^ 3 // r 2 * r 2 = r 4 ,而不是r 3 强>