识别编译器产生的汇编程序中的某些组件

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 有交替的颜色来标记检查循环条件的部分与执行循环体的部分。