|
除了简单的加减乘除外,还有许多浮点运算。FPU 提供了浮点运算的高级功能,这些功能应用在科学研究或工程技术上。可用的高级功能指令如下:
指令
| 描述
| F2XM1
| 计算2的乘方(次数为ST0中的值)减去1
| FABS
| 计算ST0中的值的绝对值
| FCHS
| 改变ST0中的值的符号
| FCOS
| 计算ST0中的值的余弦
| FPATAN
| 计算ST0中的值的部分反正切
| FPREM
| 计算ST0中的值除以ST1中的值的部分余数
| FPREM1
| 计算ST0中的值除以ST1中的值的IEEE部分余数
| FPTAN
| 计算ST0中的值的部分正切
| FRNDINT
| 把ST0中的值舍入到最近的整数
| FSCALE
| 计算ST0乘以2的ST1次乘方
| FSIN
| 计算ST0中的值的正弦
| FSINCOS
| 计算ST0中的值的正弦和余弦
| FSQRT
| 计算ST0中的值的平方根
| FYL2X
| 计算ST1*logST0(以2为基数)
| FYL2XP1
| 计算ST1*log(ST0+1) (以2为基数)
|
下面程序演示 FABS, FCHS, FSQRT 的使用:
.section .data
value1:
.float 395.21
value2:
.float -9145.290
value3:
.float 64.0
.section .text
.global _start
_start:
nop
finit
flds value1
fchs
flds value2
fabs
flds value3
fsqrt
movl $1, %eax
movl $0, %ebx
int $0x80 编译连接后,在 GDB 里查看FPU堆栈里的相关值:st0 8 (raw 0x40028000000000000000)
st1 9145.2900390625 (raw 0x400c8ee5290000000000)
st2 -395.209991455078125 (raw 0xc007c59ae10000000000) 注意,值的顺序与它们被压入到 FPU 堆栈中的顺序相反。
frndint 指令使用示例:
.section .data
value1:
.float 3.65
rdown:
.byte 0x7f, 0x07
rup:
.byte 0x7f, 0x0b
.section .bss
.lcomm result1, 4
.lcomm result2, 4
.lcomm result3, 4
.section .text
.global _start
_start:
nop
finit
flds value1
frndint
fists result1
frndint
fists result2
fldcw rup
flds value1
frndint
fists result3
movl $1, %eax
movl $0, %ebx
int $0x80 编译连接后,在 GDB 里观察 3 个内存位置(result1 - result3):(gdb) x/d &result1
0x80490c4 <result1>: 4
(gdb) x/d &result2
0x80490c8 <result2>: 3
(gdb) x/d &result3
0x80490cc <result3>: 4 说明:
由输出可见,在默认情况下,frndint 是向上舍入的,所以 result1 内存的值为 4;
为了把舍入方向设置为向下舍入,舍入位被设置为 01,这使得控制寄存器的值位 0x77f,所以 result2 内存处存放的值为 3 ;
为了把舍入方向设置为向上舍入,舍入位被设置为 10,这使得控制寄存器的值位 0xb7f,所以 result3 内存处存放的值又变为了 4 。 |
|