2014-04-30 55 views
1

我想知道,應該使用什麼值來更改FPU舍入模式。更改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 - 輪向零

+0

我意識到,這應該是這樣的:最近.BYTE 0x7f的,0x00b,同比下降:.BYTE 0x7f的,0×07,高達.BYTE 0x7f的,0x70b,零:.byte 0x7f,0x77b ?? – user3448282

回答

1

的舍入類型由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