识别编译器产生的汇编程序中的某些组件
Recognize certain components in the compiler produced assembly program
这是我的问题:
给定一个标记的C代码组件,如何在编译器生成的汇编程序中找到其对应的汇编指令?
如果标记的组件是一个函数,应该很容易,只要没有重叠的汇编程序,我们就可以线性搜索,在编译器生成的代码中识别出这个函数。
那标记的组件是循环语句呢?甚至算术陈述?这个时候有什么好的解决办法吗?
谁能帮帮我?谢谢!
用 -fverbose-asm
编译。 gcc 在 asm 输出中的注释比 clang 冗长得多,变量名可以帮助您找到您正在寻找的循环,但更多时候它们只是编号的内部临时变量。不过,ivtmp
可能代表迭代变量,而不是其他表达式的临时变量。
void foo(int*p) {
for (int i=0 ; i<123456 ; i++ )
p[i] = p[i] * 4 - 1;
}
gcc 5.3 带有 -fverbose-asm -O3 -march=haswell -fno-tree-vectorize -fno-unroll-loops
compiles it to 递增指针的代码,当然使用 lea
进行移位和减法。
Clang -fverbose-asm
对循环顶部分支目标进行注释,但不注释每一行。
foo:
lea rdx, [rdi+493824] # D.2351,
.L2:
mov eax, DWORD PTR [rdi] # MEM[base: _17, offset: 0B], MEM[base: _17, offset: 0B]
add rdi, 4 # ivtmp.9,
lea eax, [-1+rax*4] # tmp111,
mov DWORD PTR [rdi-4], eax # MEM[base: _17, offset: 0B], tmp111
cmp rdx, rdi # D.2351, ivtmp.9
jne .L2 #,
ret
更复杂的代码:
要查找内部循环,请查找标签,紧接着是返回同一标签的分支。到处都会有标签,但您正在寻找一个返回标签的分支,中间没有其他标签或分支。 (对于内部没有流量控制的简单循环)。
如果代码是矢量化的,请查找包含矢量指令的循环。 (例如,大量完全展开的标量 addsd
prologue/epilogue,然后是一个微小的 addpd
内循环。)
调试信息还将每条指令与负责它的源代码行相关联。有多种使用方法,包括按照 Godbolt Compiler Explorer 的方式对 asm 输出进行着色。
gcc auto-vectorizes this simple loop 进入标量代码直到对齐指针,然后是向量内循环,然后在最后一个完整向量之后进行清理。展开的标量 prologue/epilogue 有交替的颜色来标记检查循环条件的部分与执行循环体的部分。
这是我的问题:
给定一个标记的C代码组件,如何在编译器生成的汇编程序中找到其对应的汇编指令?
如果标记的组件是一个函数,应该很容易,只要没有重叠的汇编程序,我们就可以线性搜索,在编译器生成的代码中识别出这个函数。
那标记的组件是循环语句呢?甚至算术陈述?这个时候有什么好的解决办法吗?
谁能帮帮我?谢谢!
用 -fverbose-asm
编译。 gcc 在 asm 输出中的注释比 clang 冗长得多,变量名可以帮助您找到您正在寻找的循环,但更多时候它们只是编号的内部临时变量。不过,ivtmp
可能代表迭代变量,而不是其他表达式的临时变量。
void foo(int*p) {
for (int i=0 ; i<123456 ; i++ )
p[i] = p[i] * 4 - 1;
}
gcc 5.3 带有 -fverbose-asm -O3 -march=haswell -fno-tree-vectorize -fno-unroll-loops
compiles it to 递增指针的代码,当然使用 lea
进行移位和减法。
Clang -fverbose-asm
对循环顶部分支目标进行注释,但不注释每一行。
foo:
lea rdx, [rdi+493824] # D.2351,
.L2:
mov eax, DWORD PTR [rdi] # MEM[base: _17, offset: 0B], MEM[base: _17, offset: 0B]
add rdi, 4 # ivtmp.9,
lea eax, [-1+rax*4] # tmp111,
mov DWORD PTR [rdi-4], eax # MEM[base: _17, offset: 0B], tmp111
cmp rdx, rdi # D.2351, ivtmp.9
jne .L2 #,
ret
更复杂的代码:
要查找内部循环,请查找标签,紧接着是返回同一标签的分支。到处都会有标签,但您正在寻找一个返回标签的分支,中间没有其他标签或分支。 (对于内部没有流量控制的简单循环)。
如果代码是矢量化的,请查找包含矢量指令的循环。 (例如,大量完全展开的标量 addsd
prologue/epilogue,然后是一个微小的 addpd
内循环。)
调试信息还将每条指令与负责它的源代码行相关联。有多种使用方法,包括按照 Godbolt Compiler Explorer 的方式对 asm 输出进行着色。
gcc auto-vectorizes this simple loop 进入标量代码直到对齐指针,然后是向量内循环,然后在最后一个完整向量之后进行清理。展开的标量 prologue/epilogue 有交替的颜色来标记检查循环条件的部分与执行循环体的部分。