ASM - math operations without FPU

大兔子大兔子 提交于 2020-01-17 08:13:14

问题


I'm looking for a routine, which help me to do any of operation on floating point numbers (it can be addition), but without using Floating Point Unit (FPU).

I have to make a program, which compares time of doing operation without FPU and with FPU. Second part, with using FPU is done, but I can't find any good routine.


回答1:


Not sure why people are all shocked about the complexity. Addition, subtraction and multiplication are not terribly difficult. You will need to split the numbers into sign, mantissa and exponent then use integer math to calculate the result and finally put it back into a float. I happen to have sample code for float multiplication (64 bit GAS syntax):

.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"

Special cases for zero, nan, inf, overflow and such are left as an excercise to the reader :)



来源:https://stackoverflow.com/questions/21687312/asm-math-operations-without-fpu

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!