Linux汇编之SIMD整数

汇编 2015年03月16日 ,

Linux汇编SIMD整数

Intel的单指令多数据(Single Instruction Multiple Data, SIMD)技术提供了定义整数的其他方式,其允许处理器同时对一组多个整数执行数学运算。SIMA架构使用打包的整数数据类型,打包的整数是能够表示多个整数值的一系列字节。可以把字节系列看成是一个整体,对它执行数学操作,并行地处理系列中的各个整数值。本文中枫竹梦介绍Linux汇编语言(ASM)中可用的不同SIMD打包整数类型。

MMX整数

多媒体扩展(Multimedia Extension, MMX)技术中包括3种新的整数类型:

  • 64位打包字节整数
  • 64位打包字整数
  • 64位打包双字整数

以上每种数据类型都可以把多个整数数据元素包含单一的MMX寄存器中。如:

MMX数据类型

注意:MMX寄存器被映射到FPU(浮点运算单元)寄存器,所以使用MMX寄存器时要把FPU中存储的数据保存到内存中。

传送MMX整数

可以使用MOVQ指令把数据传送到MMX寄存器中,但是必须确定当前应用程序将使用3种打包数据格式中的哪一种。MOVQ格式如下:

movq source, destination

其中sourcedestination可以是MMX寄存器、SSE寄存器或者64位的内在位置(不能在内存间传送MMX整数)。如下演示程序:

# mmx.s - By furzoom @ Mar 14, 2015
.section .text
values1:
.int 1, -1
values2:
.byte 0x10, 0x05, 0xff, 0x32, 0x47, 0xe4, 0x00, 0x01
.section .text
.globl _start
_start:
nop
movq values1, %mm0
movq values2, %mm1
movl $1, %eax
movl $0, %ebx
int $0x80

该程序定义两个数据数组,第一组定义了2个双字带符号整数,第二级定义了8个字节带符号整数值。接着将两组数据传送到两个MMX寄存器中。调试运行如下:

[mn@furzoom asm]$ as -gstabs -o mmx.o mmx.s
[mn@furzoom asm]$ ld -o mmx mmx.o
[mn@furzoom asm]$ gdb -q mmx
Reading symbols from /home/mn/Desktop/Documents/asm/mmx...done.
(gdb) break *_start+1
Breakpoint 1 at 0x8048065: file mmx.s, line 11.
(gdb) run
Starting program: /home/mn/Desktop/Documents/asm/mmx

Breakpoint 1, _start () at mmx.s:11
11        movq values1, %mm0
(gdb) step
12        movq values2, %mm1
(gdb) step
13        movl $1, %eax
(gdb) print $mm0
$1 = {uint64 = -4294967295, v2_int32 = {1, -1}, v4_int16 = {1, 0, -1, -1},
  v8_int8 = {1, 0, 0, 0, -1, -1, -1, -1}}
(gdb) print $mm1
$2 = {uint64 = 72308588487312656, v2_int32 = {855573776, 16835655}, v4_int16 = {
    1296, 13055, -7097, 256}, v8_int8 = {16, 5, -1, 50, 71, -28, 0, 1}}
(gdb) print/x $mm1
$3 = {uint64 = 0x100e44732ff0510, v2_int32 = {0x32ff0510, 0x100e447}, v4_int16 = {
    0x510, 0x32ff, 0xe447, 0x100}, v8_int8 = {0x10, 0x5, 0xff, 0x32, 0x47, 0xe4,
    0x0, 0x1}}
(gdb) 

由于调试器不知道使用的是哪个数据格式,所以显示了所有可能的情况。

SSE整数

流化SIMD扩展(Streaming SIMD Extension, SSE)技术提供用于处理打包数据的8个128位XMM寄存器(XMM0~XMM7)。SSE2技术提供了4种额外的打包带符号整数数据类型:

  • 128位打包字节整数
  • 128位打包字整数
  • 128位打包双字整数
  • 128位打包四字整数

如:
XMM整数

传送SSE整数

MOVDQAMOVDQU指令用于把128位数据传送到XMM寄存器中,或者在XMM寄存器之间传送数据,助记符AU分别代表对准和不对准,它们表示数据是如何存储在内存中的,用于将数据对准到内存位置的16字节边界。指令格式如下:

movdqa source, destination

其中sourcedestination可以是SSE的128位寄存器或者128位的内在位置(不能在两个内存间传送数据)。当使用对准的数据时,SSE指令执行的更快。如果程序对未对准的数据使用MOVDQA指令,就会造成硬件异常。

如下演示程序演示如何使用SSE指令传送数据:

# sse.s - By furzoom @ Mar 15, 2015
.section .data
values1:
.int 1, -1, 0, 135246
values2:
.quad 1, -1
.section .text
.globl _start
_start:
nop
movdqu values1, %xmm0
movdqu values2, %xmm1

movl $1, %eax
movl $0, %ebx
int $0x80

该程序定义两个数据数组,第一组定义了4个双字带符号整数,第二级定义了2个四字带符号整数值。接着将两组数据传送到两个SSE寄存器中。调试运行如下:

[mn@furzoom asm]$ as -gstabs -o sse.o sse.s
[mn@furzoom asm]$ ld -o sse sse.o
[mn@furzoom asm]$ gdb -q sse
Reading symbols from /home/mn/Desktop/Documents/asm/sse...done.
(gdb) break *_start+1
Breakpoint 1 at 0x8048075: file sse.s, line 11.
(gdb) run
Starting program: /home/mn/Desktop/Documents/asm/sse

Breakpoint 1, _start () at sse.s:11
11        movdqu values1, %xmm0
(gdb) step
12        movdqu values2, %xmm1
(gdb) step
14        movl $1, %eax
(gdb) print $xmm0
$1 = {v4_float = {1.40129846e-45, -nan(0x7fffff), 0, 1.89520012e-40}, v2_double = {
    -nan(0xfffff00000001), 2.8699144274488922e-309}, v16_int8 = {1, 0, 0, 0, -1,
    -1, -1, -1, 0, 0, 0, 0, 78, 16, 2, 0}, v8_int16 = {1, 0, -1, -1, 0, 0, 4174,
    2}, v4_int32 = {1, -1, 0, 135246}, v2_int64 = {-4294967295, 580877146914816},
  uint128 = 0x0002104e00000000ffffffff00000001}
(gdb) print $xmm1
$2 = {v4_float = {1.40129846e-45, 0, -nan(0x7fffff), -nan(0x7fffff)}, v2_double = {
    4.9406564584124654e-324, -nan(0xfffffffffffff)}, v16_int8 = {1, 0, 0, 0, 0, 0,
    0, 0, -1, -1, -1, -1, -1, -1, -1, -1}, v8_int16 = {1, 0, 0, 0, -1, -1, -1,
    -1}, v4_int32 = {1, 0, -1, -1}, v2_int64 = {1, -1},
  uint128 = 0xffffffffffffffff0000000000000001}
(gdb) 

在执行完MOVDQU指令后,XMM0XMM1寄存器包含数据段中定义的数据值。

(完)

如无特别说明,本站文章皆为原创,若要转载,务必请注明以下原文信息:
日志标题:《Linux汇编之SIMD整数》
日志链接:http://furzoom.com/linux-asm-simd/
博客名称:枫竹梦

2 篇回应 (访客:1 篇, 博主:1 篇)

  1. ITKep 2015-17-03

    表示看不懂,隔行如隔山啊!

    #-49楼
    • 马 岩 2015-17-03

      了解计算机中数的存储与运算方式,对编程有益处。哪怕你不用C语言,用javascript都是有益处的!更懂计算机,才能让计算机更好的干活!

插入图片

NOTICE1:请申请gravatar头像,没有头像的评论可能不会被回复!

回到顶部