第41部分-Linux x86 64位汇编MMX使用

第41部分-Linux x86 64位汇编MMX使用

使用MMX架构需要一下步骤

  1. 从整数值创建打包整数值
  2. 把打包整数值加载到MMX寄存器中
  3. 对打包整数值执行MMX数学操作。
  4. 从MMX寄存器获得结果放到内存位置中。

加载和获得打包的整数值,使用movq指令把整数值传送进/出MMX寄存器。

对比打包整数值操作,同时计算多个结果值,单一一组标志不能表示操作的结果。可以从执行数学操作的3种溢出方法中选择: 环绕/带符号饱和/无符号饱和。

带符号和无符号饱和运算方法把溢出情况的结果设置为预先设置的值。

正溢出就设置为最大值,负溢出就设置为最小值,数学角度没有意义。主要是应用于执行图像计算显示图片,正溢出就是最大值为白色,负溢出就是最小值为黑色。

操作的指令有如下:

MMX加法示例

两个long类型整数值存储到单一内存位置,创建打包双字整数值。移动到MMX寄存器,然后通过PADD指令相加,存放到MM0中,最后复制到result内存位置。

.section .data
value1:
   .int 10, 20
value2:
   .int 30, 40
.section .bss
   .lcomm result, 8
.section .text
.globl _start
_start:
   nop
   movq value1, %mm0
   movq value2, %mm1
   paddd %mm1, %mm0
   movq %mm0, result

   movl $60, %eax
   movl $0, %ebx
   syscall

编译:

as -g -o mmxadd.o mmxadd.s

ld -o mmxadd mmxadd.o

使用gdb调试,在退出前断点进行查看结果。

(gdb) x /2d &value1

0x6000d8:   10  20

(gdb) x /2d &value2

0x6000e0:   30  40

(gdb) x /2x &result

0x6000e8 <result>: 0x00000028  0x0000003c

gdb>info all

st0            <invalid float value>   (raw 0xffff0000003c00000028)

可以在st0寄存器中看到两个结果。MM0就是存在st0中的。

 

    1. MMX乘法示例

乘法比较困难,因为乘法生产的结果可能会比输入操作数大得多。乘法允许使用两条指令完成乘法操作。

PMULL把每对打包字整数值相乘,结果的低16位存放到目标寄存器。

PMULH把每对打包字整数值相乘,结果的高16位存放到目标寄存器。

带符号的是PMULLW和PMULHW,无符号的是PMULLUW和PMULHUW。

     乘法系列中还有一个附加指令是PMADDWD指令。

MMX逻辑和移位

MMX中可用的布尔逻辑指令如下图:

SOURCE可以是MMX寄存器或者64位的内存位置,目标必须是MMX寄存器。

 

MMX比较

两个值比较指令如下图:

比较结果存放到目标打包整数值中。

      1. 示例

比较的示例如下,value1和value2被设置为保存4个short类型的整数值。加载到MMX寄存器中,然后使用PCMPEQW指令比较打包整数值的4个字值。结果存放到MM0寄存器,然后传送到result中。

.section .data
value1:
   .short 10, 20, -30, 40
value2:
   .short 10, 40, -30, 45
.section .bss
   .lcomm result, 8
.section .text
.globl _start
_start:
   nop
   movq value1, %mm0
   movq value2, %mm1
   pcmpeqw %mm1, %mm0
   movq %mm0, result

   movl $60, %eax
   movl $0, %ebx
   syscall

as -g -o mmxcomp.o mmxcomp.s

ld -g -o mmxcomp mmxcomp.o

使用gdb进行调试,开始时如下;

(gdb) x /x &value1

0x6000d8:   0x0014000a

(gdb) x /x &value2

0x6000e0:   0x0028000a

(gdb) x /x &result

0x6000e8 <result>: 0x00000000

执行移动到MM0/MM1后,ST0/ST1的寄存器如下:

st0 <invalid float value>  (raw 0xffff0028ffe20014000a)

st1 <invalid float value>  (raw 0xffff002dffe20028000a)

执行pcmpeqw后st0寄存器如下:

st0 <invalid float value>  (raw 0xffff0000ffff0000ffff)

(gdb) x /8x & result

0x6000e8 <result>: 0x0000ffff  0x0000ffff

我们发现结果如下:

相等的打包整数值,结果相等等于FFFF,不相等的等于0000。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值