|
FSCALE 指令
FSCALE 指令计算 ST(0) 乘以 2 的 ST(1) 次乘方。如果 ST(1) 为正则结果放大,如果 ST(1) 为负则结果缩小。下面程序演示这个指令的用法:
.section .data
value:
.float 10.0
scale1:
.float 2.0
scale2:
.float -2.0
.section .bss
.lcomm result1, 4
.lcomm result2, 4
.section .text
.global _start
_start:
nop
finit
flds scale1
flds value
fscale
fsts result1
flds scale2
flds value
fscale
fsts result2
movl $1, %eax
movl $0, %ebx
int $0x80 在 gdb 中查看相关内存:(gdb) x/f &result1
0x80490b8 <result1>: 40
(gdb) x/f &result2
0x80490bc <result2>: 2.5
对数函数指令 FYL2X
FYL2X 执行如下计算:
ST(1) * log2 (ST(0))
另外一个变形的指令 FYL2X1 还执行这样的运算:
ST(1) * log2 (ST(0) + 1.0)
虽然 FPU 的对数函数只提供以 2 为底数的对数运算,但是可以使用其他对数底数执行计算。对数换底公式为:
![]()
推导换底公式,假设:a^k = x --- 1
b^n = x --- 2
b^m = a --- 3 将 3 代入 1 得:由 2 和 4 得:即:从而:再由 1,2,3 可知:k=log(a)x
n=log(b)x
m=log(b)a 所以可以推出换底公式。
下面就用 FYL2X 指令来实现底数为 10 的对数:
根据换底公式,可有:log(b)X = (1/log(2) b) * log(2) X)
程序代码:
.section .data
value:
.float 12.0
base:
.float 10.0
.section .bss
.lcomm result, 4
.section .text
.global _start
_start:
nop
finit
fld1 #加载 1.0
flds base #加载 10.0 (ST1=1.0, ST0=10.0)
fyl2x #log(2)10.0 (先弹出ST0和ST1再计算,结果存入 ST0 中, )
fld1
fdivp #计算 1/log(2)10.0 (fdivp 是 st0/st1)
fld1
flds value
fyl2x #计算 log(2)12.0
fmul %st(1), %st(0) # log(2)12.0 / log(2)10.0 (换底操作)
fsts result #存储结果
movl $1, %eax
movl $0, %ebx
int $0x80 最后在 gdb 中查看一下结果:(gdb) x/f &result
0x80490ac <result>: 1.07918119 结果正确。 |
|