【发布时间】:2015-12-15 07:27:35
【问题描述】:
这是一道作业题。 我正在尝试从以下汇编代码(x86 linux 机器,使用 gcc -O2 优化编译)中获取信息。我已经评论了每个部分以显示我所知道的。我的大部分假设可能是错误的,但我已经做了足够多的搜索,以至于我知道我应该在这里问这些问题。
.section .rodata.str1.1,"aMS",@progbits,1
.LC0:
.string "result %lx\n" //Printed string at end of program
.text
main:
.LFB13:
xorl %esi, %esi // value of esi = 0; x
movl $1, %ecx // value of ecx = 1; result
xorl %edx, %edx // value of edx = 0; Loop increment variable (possibly mask?)
.L2:
movq %rcx, %rax // value of rax = 1; ?
addl $1, %edx // value of edx = 1; Increment loop by one;
salq $3, %rcx // value of rcx = 8; Shift left rcx;
andl $3735928559, %eax // value of eax = 1; Value AND 1 = 1;
orq %rax, %rsi // value of rsi = 1; 1 OR 0 = 1;
cmpl $22, %edx // edx != 22
jne .L2 // if true, go back to .L2 (loop again)
movl $.LC0, %edi // Point to string
xorl %eax, %eax // value of eax = 0;
jmp printf // print
.LFE13: ret // return
我应该把它变成下面填空的C代码
#include <stdio.h>
int main()
{
long x = 0x________;
long result = ______;
long mask;
for (mask = _________; mask _______; mask = ________) {
result |= ________;
}
printf("result %lx\n",result);
}
我有几个问题和健全性检查,我想确保我做对了,因为我发现的类似示例都不是针对优化代码的。在自己编译一些试验后,我得到了一些接近的结果,但 L2 的中间部分总是关闭。
我的理解
一开始,esi 与自身异或,结果为 0,用 x 表示。然后将 1 添加到 ecx,这将由变量 result 表示。
x = 0; result = 1;
然后,我相信一个循环增量变量存储在 edx 中并设置为 0。这将用于 for 循环的第三部分(更新表达式)。我还认为这个变量必须是掩码,因为稍后将 1 添加到 edx,表示循环增量(掩码 = mask++),以及在 for 循环的中间部分比较 edx(测试表达式又名掩码!= 22 )。
mask = 0; (in a way)
然后进入循环,将 rax 设置为 1。我不明白它在哪里使用,因为我没有声明第四个变量,尽管它稍后显示被和归零。
movq %rcx, %rax;
然后循环变量加一
addl $1, %edx;
下一部分对我来说意义最小
我觉得接下来的三个操作构成了循环的主体表达式,但是我不知道如何处理它们。它会导致类似于 result |= x ... 但我不知道还有什么
salq $3, %rcx
andl $3735928559, %eax
orq %rax, %rsi
其余的我觉得我掌握得很好。进行比较(如果 mask != 22,再次循环),并打印结果。
我遇到的问题 我不明白几件事。
1) 我不明白如何计算我的变量。似乎有 3 个硬编码的,以及在程序集中找到的一个增量或临时存储变量(rax、rcx、rdx、rsi)。我认为 rsi 将是 x ,而 rcx 将是 result,但我不确定 mask 是 rdx 还是 rax,无论哪种方式,最后一个变量是什么是吗?
2) 我不确定的 3 个表达式是做什么的?我觉得我以某种方式将它们与增量混淆了,但是在不知道变量的情况下我不知道如何解决这个问题。
任何和所有的帮助都会很棒,谢谢!
【问题讨论】:
-
我查看了系统如何处理 for 循环,增量是比较之前的行,但是这些值似乎不会对齐,因为增量存储在掩码中,并且比较之前的行没有提到掩码
标签: c loops assembly x86 reverse-engineering