User Tools

Site Tools


Action disabled: register
using_20the_20fscale_20instruction

Using the fscale instruction

by Tony Tooth, January 2016. Edited by Tony Tooth April 2018

Randall Hyde's book “The Art of Assembly Language” omits to cover or even mention the fscale instruction in the main text or in the index, although it is in his Table B-2: Floating Point Instruction Set.

fscale (I discovered only late in 2015 - after more than 10 years experience programming in assembly language) is a fast and efficient way to implement the exponential function in assembly language. The way I did this hitherto was incredibly cumbersome. I have written a simple sub-routine in assembly language to illustrate the use of fscale. Note that my illustrative routine does not check for out-of-bounds numbers.

      DEF FN_fractpower(num, pow)
      LOCAL pass&, res
 
      PRIVATE Fract%, P%
 
      num = 1.0*num : pow = 1.0*pow
 
      IF Fract% = 0 THEN
        DIM P% 1000
 
        FOR pass& = 0 TO 2 STEP 2
          [opt pass&
          .Fract%
 
          finit
          fld tbyte [^num]
          fld1
          fxch st1
          fyl2x             ;Calculates st1 = st1*lg2(st0) where st = 1.0 & pops st0
          fld tbyte [^pow]
          fmulp st1,st0     ;Calculates N = pow*lg2(num)
          fld st0           ;Make a copy 0f what's at st0, so st1 & st0 are the same number
          frndint           ;Round st0 t0 the nearest Integer
          fsub st1,st0      ;Calculates Ans = N - Int(N) where Ans will be between -1.0 & +1.0
          fxch st1          ;Exchange st1 with st0
          f2xm1             ;Calculate 2^Ans - 1
          fld1
          faddp st1,st0     ;Add 1 t0 the above so we have left 2^Ans
          fscale            ;Automatically calculates st0 = (2^st1)*st0 which is 2^N = num^pow
          fstp st1          ;Throw away st1
          fstp tbyte [^res] ;Answer is at st0
 
          ret
          ]
        NEXT pass&
      ENDIF
 
      CALL Fract%
 
      = res

Edit by Richard Russell, January 2016:

An alternative way of computing the exponential function in BB4W v6 assembly language is to call the internal EXP routine, which is exposed via the @fn%() jump table, as follows (it uses fscale internally):

        @% = &1415
        REPEAT
          INPUT '"Enter a value: " x
          PRINT "BBC version of EXP(x) = "; EXP(x)
          PRINT "ASM version of EXP(x) = "; FNexp(x)
        UNTIL FALSE
        END
 
        DEF FNexp(x)
        LOCAL P%, y
        PRIVATE X%
        IF X% = 0 THEN
          DIM P% 50
          [OPT 2
          .X%
          mov edx,[^x]
          mov ecx,[^x+4]
          mov bx,[^x+8]
          call @fn%(16) ; xexp
          mov [^y],edx
          mov [^y+4],ecx
          mov [^y+8],bx
          ret
          ]
        ENDIF
        x *= 1.0
        CALL X%
        = y
This website uses cookies. By using the website, you agree with storing cookies on your computer. Also you acknowledge that you have read and understand our Privacy Policy. If you do not agree leave the website.More information about cookies
using_20the_20fscale_20instruction.txt · Last modified: 2024/01/05 00:21 by 127.0.0.1