【发布时间】:2021-04-10 02:31:02
【问题描述】:
我无法破译这个给定的汇编代码:
1 unknown5:
2 pxor %xmm0, %xmm0
3 movl $0, %eax
4 jmp .L13
5 .L14:
6 movss (%rdx,%rax,4), %xmm1
7 mulss (%rsi,%rax,4), %xmm1
8 addss %xmm1, %xmm0
9 addq $1, %rax
10 .L13:
11 cmpq %rdi, %rax
12 jb .L14
13 rep ret
我认为正在发生的事情:
- 1:函数名为 unknown5()
- 2:设置浮点返回寄存器为0
- 3:设置32位返回寄存器为0
- 4:跳转到 10:
- 11:如果 %rdi > %rax,则转到 5:,否则转到 13:
- 6: %xmm1 = %rdx+%rax+4
- 7: %xmm1 *= %rsi+%rax+4
- 8: %xmm0 += %xmm1
- 9: %rax += 1
- 13:返回 %eax、%rax 或 %xmm0??
我不知道函数的可能参数是什么,也不知道每个寄存器代表什么。我知道 %rdi、%rsi 和 %rdx 是第一个、第二个和第三个参数(由于单精度操作可能是浮点指针?),%xmm0、%xmm1 是第一个和第二个浮点参数(或本地变量?)。我也知道 %rax 是 64 位返回寄存器,但我不确定为什么在这里使用它。有人可以详细说明并纠正我的理解吗?谢谢。
【问题讨论】:
-
程序集没有“局部变量”,您正在考虑“寄存器”。
-
我知道,我应该澄清一下,我需要将上述程序集转换为 C,因此寄存器将表示函数参数或局部变量,具体取决于
-
只要有一点经验,您就会认识到这是一个典型的
while循环。 -
有趣的事实:这似乎是由
gcc -O1编译的(mov $0, %eax而不是xor %eax,%eax,并且在第一次迭代时跳转到循环而不是提升第一次检查),与一些早于 GCC8 的 GCC 版本(rep ret因为它的-mtune=generic默认仍然关心 AMD K8/K10(例如 Phenom II 和更早版本))。也是实际的gcc,而不是g++,因为g++ -O1 / -O0倾向于制作愚蠢的“while”循环,顶部有一个条件分支(Why are loops always compiled into "do...while" style (tail jump)?)
标签: c assembly floating-point x86-64 reverse-engineering