linux - 更改 FPU 舍入模式

标签 linux assembly x86 att 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 — 向零舍入

最佳答案

舍入类型由 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/

相关文章:

汇编中的 C 调用约定(64 位)- scanf

linux - 不执行任何操作的简单 _start 末尾的段错误

linux - Yocto 安装和使用 toastr

c++ - 什么 C++ 代码编译成 x86 REP 指令?

python - DBus.Error.AccessDenied : Rejected. DBUS 通过 TCP

c++ - 设置 SSE 寄存器中的最后或前 n 位

linux - 从 perf 获取 PEBS 数据线性地址

visual-studio - 为什么寄存器 ax 中的内存整数之和是正确的,而寄存器 eax 中的内存整数之和却不是正确的?

在 centos 9 上找不到 libl -/usr/bin/ld : cannot find -ll

linux - Bash 和 Linux shell 一样吗?