首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >不带FPU的ASM数学运算

不带FPU的ASM数学运算
EN

Stack Overflow用户
提问于 2014-02-11 04:32:12
回答 1查看 418关注 0票数 0

我正在寻找一个例程,它可以帮助我在浮点数上做任何运算(它可以是加法),但不使用浮点单元(FPU)。

我必须做一个程序,比较在没有FPU和有FPU的情况下操作的时间。第二部分,使用FPU已经完成,但我找不到任何好的例程。

EN

回答 1

Stack Overflow用户

发布于 2014-02-11 21:11:20

不知道为什么人们都对它的复杂性感到震惊。加法、减法和乘法都不是很难。您将需要将数字拆分为符号、尾数和指数,然后使用整数数学来计算结果,最后将其放回浮点数。我碰巧有浮点乘法(64位GAS语法)的示例代码:

代码语言:javascript
复制
.globl main
main:
    subq $8, %rsp
    leaq format1(%rip), %rdi
    leaq (%rsp), %rsi
    leaq 4(%rsp), %rdx
    xor %eax, %eax
    call scanf

    movl (%rsp), %eax           # x
    movl 4(%rsp), %ecx          # y

    movl %eax, %edx             # edx = x
    xorl %ecx, %eax             # sgn(x*y) = sgn(x) ^ sgn(y)
    andl $0x80000000, %eax      # eax has correct sign bit now
    movl %ecx, %esi             # esi = y
    shrl $23, %esi
    andl $0xff, %esi            # esi = exp(y)
    movl %edx, %edi             # edi = x
    shrl $23, %edi
    andl $0xff, %edi            # edi = exp(x)
    addl %esi, %edi             # exp(x*y) = exp(x) + exp(y)
    subl $0x7f+23, %edi         # subtract bias and mantissa bits

    andl $0x007fffff, %edx      # edx = man(x)
    andl $0x007fffff, %ecx      # ecx = man(y)
    orl $0x00800000, %ecx       # put implicit leading 1 bit
    orl $0x00800000, %edx       # to both mantissas
    imulq %rcx, %rdx            # man(x*y) = man(x) * man(y)
    bsrq %rdx, %rcx             # find first set bit
    subl $23, %ecx              # leave 23 bits
    shrq %cl, %rdx              # shift the rest out
    andl $0x007fffff, %edx      # chop off implicit leading 1 bit
    addl %ecx, %edi             # adjust the exponent by the bits shifted out

    shll $23, %edi              # shift exponent into position
    orl %edi, %eax              # put exponent into result
    orl %edx, %eax              # put mantissa into result

    movss (%rsp), %xmm0
    movss 4(%rsp), %xmm1
    movd %eax, %xmm2
    cvtss2sd %xmm0, %xmm0
    cvtss2sd %xmm1, %xmm1
    cvtss2sd %xmm2, %xmm2
    movl $3, %eax
    leaq format2(%rip), %rdi
    call printf

    addq $8, %rsp
    ret
.data
    format1: .asciz "%f %f"
    format2: .asciz "%f * %f = %f\n"

对于zero、nan、inf、overflow之类的特殊情况,留给读者作为练习:)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21687312

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档