Assembly NASM协处理器-舍入效果不好

Assembly NASM协处理器-舍入效果不好,assembly,x86,nasm,fpu,Assembly,X86,Nasm,Fpu,我写了一个计算子弹体积的程序。对于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 [op

我写了一个计算子弹体积的程序。对于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

在这里,您尝试加载两个整数,就像它们是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寄存器堆栈上。源操作数可以是字、双字或四字整数。它已加载 没有舍入误差。源操作数的符号将保留


除了Michael提到的问题之外,您似乎在使用radius4而不是radius3

FMUL st0,st0;;st0-半径^2
FMUL st0,st0;;st0-半径^3/r2*r2=r4,而不是r3


谢谢你,伙计。没错,我犯了这个错误:)。对于半径,我仍然有FLD,但对于操作符,我设置了FILD。我似乎一切都很好,但现在我得到了3分。也对了,谢谢。我会修好的。但毕竟,以我的方式(半径为4次方),我应该得到9,而不是我现在得到的3。出什么问题了?@Martin你能在问题的底部添加一个代码块,使上面两个问题得到解决,这样我们就可以看到你的代码现在是什么样子了?但是,请保留现有的代码块,这样已经在这里给出的答案就不会让将来阅读该问题的人感到困惑。好的,没问题。在得到预期结果之前:)。事实证明,我已经忘记了一次无条件跳转。不要编辑问题并删除所有原始错误代码,因为人们不知道代码失败的原因和位置。如果您愿意,可以在下面添加固定代码