我想知道,我应该使用什么值来更改 FPU 舍入模式。
.data
nearest:
??
down:
??
up:
??
zero:
??
.text
.global round
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %ecx
cmpl $1, %ecx
je
fldcw nearest
cmpl $2, %ecx
je
fldcw down
cmpl $3, %ecx
je
fldcw up
cmpl $4, %ecx
je
fldcw zero
leave
ret
我发现了这样的东西:
down:
.byte 0x7f, 0x07
up:
.byte 0x7f, 0x0b
但我不知道为什么有人用它。我知道我应该像这样更改 8 位和 9 位: 00 — 四舍五入到最近的 01 — 向下舍入(向负无穷大) 10 — 向上舍入(朝向正无穷大) 11 — 向零舍入
最佳答案
舍入类型由 FPU 控制字中的两位决定。您可以在此处获取有关 FPU 的信息:http://www.website.masmforum.com/tutorials/fptute/fpuchap1.htm .只改变这两位而保持其他不变有点棘手。看看我的例子。我试图尽可能接近您的代码:
.data
num: .double 6.5 # play with the number!
old: .word 0
nearest: .word 0x0000
down: .word 0x0400
up: .word 0x0800
zero: .word 0x0C00
result: .double 0
fmt1: .asciz "nearest: %f -> %f\n"
fmt2: .asciz "down: %f -> %f\n"
fmt3: .asciz "up: %f -> %f\n"
fmt4: .asciz "zero: %f -> %f\n"
.text
.globl main
main:
fstcw old # store old control word
movw old, %ax
andb $0b11110011, %ah # clear RC field
orw %ax, nearest
orw %ax, down
orw %ax, up
orw %ax, zero
fldcw nearest # banker's rounding
call round
mov $fmt1, %esi
call out
fldcw down # down toward -infinity
call round
mov $fmt2, %esi
call out
fldcw up # up toward +infinity
call round
mov $fmt3, %esi
call out
fldcw zero # truncating
call round
mov $fmt4, %esi
call out
fldcw old # restore old control word
xor %eax, %eax # exit(0)
ret # GCC only needs RET
round:
fldl num
frndint
fstpl result
ret
out:
push result+4
push result
push num+4
push num
push %esi
call printf # "%f" needs a double
add $20, %esp
ret
关于linux - 更改 FPU 舍入模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23392070/