汇编代码 x86
Assembly code x86
所以我完全不懂汇编代码,也阅读它们
所以我有一个简单的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
给我以下汇编代码
saxpy:
.LFB0:
.cfi_startproc
movss a(%rip), %xmm1
xorl %eax, %eax
.p2align 4,,10
.p2align 3
.L3:
movss x(%rax), %xmm0
addq , %rax
mulss %xmm1, %xmm0
addss y-4(%rax), %xmm0
movss %xmm0, z-4(%rax)
cmpq 2144, %rax
jne .L3
rep ret
.cfi_endproc
我知道循环展开已经发生
但我无法理解背后的意图和想法
addq , %rax
mulss %xmm1, %xmm0
addss y-4(%rax), %xmm0
movss %xmm0, z-4(%rax)
谁能解释一下,4的用法,以及
这些陈述是什么意思
y-4(%rax)
x
、y
和 z
是全局数组。您遗漏了声明符号的列表末尾。
I put your code on godbolt for you,定义了必要的全局变量(并修复了缩进)。看底部。
顺便说一句,这里没有展开。在循环中每个标量单精度 mul 和 add 都有一个。试试 -funroll-loops
看看它展开。
With -march=haswell
, gcc will use an FMA instruction。如果您通过省略 -fno-tree-vectorize
来解除编译器的瘫痪,并且 #define ARRAY_SIZE
很小,比如 100,它会完全展开循环,其中大部分是 32 字节的 FMA ymm 指令,以一些 16 字节的 FMA xmm 结束。
Also, what is the need to add an immediate value 4 to rax register.
which is done as per the statement "addq , %rax"
循环将指针递增 4 个字节,而不是使用缩放索引寻址模式。
查看 https://whosebug.com/questions/tagged/x86 上的链接。此外,使用调试器单步执行代码通常是确保您了解它在做什么的好方法。
所以我完全不懂汇编代码,也阅读它们
所以我有一个简单的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
给我以下汇编代码
saxpy:
.LFB0:
.cfi_startproc
movss a(%rip), %xmm1
xorl %eax, %eax
.p2align 4,,10
.p2align 3
.L3:
movss x(%rax), %xmm0
addq , %rax
mulss %xmm1, %xmm0
addss y-4(%rax), %xmm0
movss %xmm0, z-4(%rax)
cmpq 2144, %rax
jne .L3
rep ret
.cfi_endproc
我知道循环展开已经发生 但我无法理解背后的意图和想法
addq , %rax
mulss %xmm1, %xmm0
addss y-4(%rax), %xmm0
movss %xmm0, z-4(%rax)
谁能解释一下,4的用法,以及 这些陈述是什么意思 y-4(%rax)
x
、y
和 z
是全局数组。您遗漏了声明符号的列表末尾。
I put your code on godbolt for you,定义了必要的全局变量(并修复了缩进)。看底部。
顺便说一句,这里没有展开。在循环中每个标量单精度 mul 和 add 都有一个。试试 -funroll-loops
看看它展开。
With -march=haswell
, gcc will use an FMA instruction。如果您通过省略 -fno-tree-vectorize
来解除编译器的瘫痪,并且 #define ARRAY_SIZE
很小,比如 100,它会完全展开循环,其中大部分是 32 字节的 FMA ymm 指令,以一些 16 字节的 FMA xmm 结束。
Also, what is the need to add an immediate value 4 to rax register. which is done as per the statement "addq , %rax"
循环将指针递增 4 个字节,而不是使用缩放索引寻址模式。
查看 https://whosebug.com/questions/tagged/x86 上的链接。此外,使用调试器单步执行代码通常是确保您了解它在做什么的好方法。