汇编代码x86

时间:2015-09-12 04:01:45

标签: gcc assembly x86 intel compiler-optimization

所以即使是汇编代码中的总菜鸟也要阅读它们

所以我有一个简单的c代码

void saxpy()
{
  for(int i = 0; i < ARRAY_SIZE; i++) {
  float product = a*x[i];
  z[i] = product + y[i];
}
}

以及使用

编译时的等效汇编代码
gcc -std=c99 -O3 -fno-tree-vectorize -S code.c -o code-O3.s 

给我以下的asssembly代码

saxpy:
.LFB0:
.cfi_startproc
movss   a(%rip), %xmm1
xorl    %eax, %eax
.p2align 4,,10
.p2align 3
.L3:
movss   x(%rax), %xmm0
addq    $4, %rax
mulss   %xmm1, %xmm0
addss   y-4(%rax), %xmm0
movss   %xmm0, z-4(%rax)
cmpq    $262144, %rax
jne .L3
rep ret
.cfi_endproc

我明白循环展开已经发生了 但我无法理解背后的意图和想法

addq    $4, %rax
mulss   %xmm1, %xmm0
addss   y-4(%rax), %xmm0
movss   %xmm0, z-4(%rax)

有人可以解释,使用4,和 这些陈述意味着什么     y-4(%rax)

1 个答案:

答案 0 :(得分:1)

xyz是全局数组。您遗漏了列表中声明符号的末尾。

I put your code on godbolt for you,定义了必要的全局变量(并修复了缩进)。看看底部。

顺便说一下,这里没有展开。每个标量单精度mul都有一个并加入循环。尝试使用-funroll-loops查看它展开。

With -march=haswell, gcc will use an FMA instruction。如果你通过省略-fno-tree-vectorize来解除编译器的瘫痪,并且#define ARRAY_SIZE很小,比如100,它会完全展开循环,主要是32byte FMA ymm指令,以16byte FMA xmm结束。

  

此外,需要向rax寄存器添加立即值4。   根据声明&#34; addq $ 4,%rax&#34;

完成

循环将指针递增4个字节,而不是使用缩放索引寻址模式。

查看https://stackoverflow.com/questions/tagged/x86上的链接。此外,使用调试器单步执行代码通常是确保您了解其执行情况的好方法。