2014-02-10 5 views
0

FPU (Floating Point Unit)를 사용하지 않고 부동 소수점 숫자에 연산을 수행하는 데 도움이되는 루틴을 찾고 있습니다 (추가 할 수 있음).FPM이없는 ASM - 수학 연산

FPU가없는 작업 시간과 FPU를 비교하는 프로그램을 만들어야합니다. FPU를 사용하여 두 번째 부분은 끝났지 만 좋은 루틴을 찾을 수 없습니다.

+0

에 대한 훈련으로 남아 있습니다 "그 사람"이되어서 미안하지만 * 왜? * 내장 FPU를 사용하는 것이 정수 연산을 사용하는 것보다 훨씬 빠릅니다. 이 숙제인가요? 그렇지 않으면 문제를 해결할 수 있습니다. – TypeIA

+4

[SoftFloat] (http://www.jhauser.us/arithmetic/SoftFloat.html)를 사용하지 않는 이유는 무엇입니까? – Leeor

+1

또한, 소프트웨어에서 부동 소수점 수에 대한 가능한 모든 연산을 수행하는 단일 "루틴"은 ... 음 ... 다소 복잡하고 복잡합니다 ... 거기에는 라이브러리가있을 것입니다. 컴파일러 (적어도'gcc')는 올바른 옵션이 주어지면 간단히 FPU가 아닌 부동 소수점 코드를 생성 할 수 있습니다. – twalberg

답변

0

사람들이 왜 복잡성에 대해 모두 충격을 받았는지 잘 모르겠습니다. 더하기, 빼기 및 곱하기가 그리 어렵지 않습니다. 숫자를 사인, 가수 및 지수로 나눠서 정수 계산을 사용하여 결과를 계산하고 마지막으로 다시 플로트에 넣어야합니다. 나는 플로트 곱하기 (64 비트 GAS 구문)에 대한 샘플 코드가하는 일 : 제로, 유모, INF, 오버 플로우에 대한

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

특별한 경우 등은 독자 : 나는 '

+0

고마워요 :-)하지만 32 비트 용 변형이 있습니까? 그리고 FASM 문법에 대해 궁금해하는데 32 비트가 있으면 32 비트이면 충분합니다. –

+0

'imulq'로 시작하는 4 개의 명령은 64 비트 부분 (사용자가 필요로하지 않는 입력과 출력 제외)입니다. 당신은 32 비트 자신을 위해 그것을 재 작성할 수 있어야하지만, 32 비트 모드에서 64 비트 곱하기는'edx' :'eax'를 사용할 것이므로 약간의 셔플이 필요할 것입니다. – Jester