Reverse Engineering challenge #87.(GCC编译器汇编代码)

This is one of the hardest ever exercises.

What does this code do?

Hint: the function has been copypasted from the guts of GCC, but in fact, it is present almost in all modern compilers, though, in different forms, but calculating the same value(s). Its function is highly important.

Second hint: f(f(x))=x.

Optimizing GCC 5.4 x86

f:
   mov edx, 31
   mov eax, 1
.L2:
   imul eax, edi
   imul edi, edi
   sub edx, 1
   jne .L2
   ret

这个函数是从GCC的内部复制粘贴过来的,但实际上,它几乎存在于所有现代编译器中,尽管形式不同,但计算的是相同的值。它的功能非常重要。

f:
        mov     edx, 31    //把立即数31送给edx寄存器
        mov     eax, 1		//把立即数1送给eax寄存器
.L2:
        imul    eax, edi		//双操作数的有符号乘,eax=eax*edi,结果存储在eax寄存器
        imul    edi, edi		//双操作数的有符号乘,edi=edi*edi,结果存储在edi寄存器
        sub     edx, 1		//edx寄存器的值减1,edx=edx-1,根据相减的结果置零标志ZF,结果不为0则置1
        jne     .L2			//相减的结果不为0则跳转
        ret

  imul的双操作数格式会按照目的操作数的大小来截取乘积。如果被丢弃的是有效位,则溢出标志位和进位标志位置1。因此,在执行了有两个操作数的IMUL操作后,必须检查这些标志位。
  汇编代码中三个寄存器,edi是输入的参数、edx负责从31递减到1、eax负责保存每次计算的结果。所以函数的功能是:递归调用30次,计算参数edi的edi * edi^2 * edi4 * ······ * edi1^6384的结果,保存在eax中返回。

你可能感兴趣的:(编程语言,#,逆向汇编,指令集,汇编语言,x86,GCC)