将汇编'shl','OR','AND','SHR'操作转换为C的参考?

时间:2018-02-07 10:04:29

标签: c assembly reverse-engineering att

我要将以下AT& T x86程序集转换为C:

  movl 8(%ebp), %edx
  movl $0, %eax
  movl $0, %ecx
  jmp .L2
.L1
  shll $1, %eax
  movl %edx, %ebx
  andl $1, %ebx
  orl %ebx, %eax
  shrl $1, %edx
  addl $1, %ecx
.L2
  cmpl $32, %ecx
  jl   .L1
  leave

但必须遵守以下框架代码:

int f(unsigned int x) {
    int val = 0, i = 0;
    while(________) {
        val = ________________;
        x = ________________;
        i++;
    }
    return val;
}

我可以告诉那个片段

.L2
  cmpl $32, %ecx
  jl   .L1

可以解释为while(i<32)。我还知道x存储在%edx中,val存储在%eax中,i存储在%ecx中。但是,我很难将while / .L1循环中的程序集转换为适合所提供的框架代码的精简高级语言。例如,shllshrlorlandl只能使用其直接C等价物(<<>>,{ {1}},|),还是有一些细微差别?

是否有针对Assembly-to-C转换的标准化指南/“备忘单”?

我理解汇编到高级转换并不总是很明确,但汇编代码中肯定有一些模式可以被一致地解释为某些C操作。

2 个答案:

答案 0 :(得分:1)

  

例如,可以简单地使用shll,shrl,orl和andl编写   他们的直接C等价物(&lt;&gt;,&gt;,|,&amp;),还是有一些细微差别   对吗?

他们可以。让我们一步一步地检查循环体:

  shll $1, %eax    // shift left eax by 1, same as "eax<<1" or even "eax*=2"
  movl %edx, %ebx
  andl $1, %ebx    // ebx &= 1
  orl %ebx, %eax   // eax |= ebx
  shrl $1, %edx    // shift right edx by 1, same as "edx>>1" = "edx/=2"

让我们

  %eax *=2
  %ebx = %edx        
  %ebx = %ebx & 1       
  %eax |= %ebx     
  %edx /= 2

ABI告诉我们(8(%ebp), %edx)%edx是x,%eax(返回值)是val:

  val *=2
  %ebx = x           // a
  %ebx = %ebx & 1    // b
  val |= %ebx        // c
  x /= 2

结合a,b,c:#2将a插入b:

  val *=2
  %ebx = (x & 1)  // b
  val |= %ebx     // c
  x /= 2

将a,b,c:#2插入b组合成c:

  val *=2
  val |= (x & 1)
  x /= 2

最后一步:结合两个&#39; val =&#39;成为一个

  val = 2*val | (x & 1)
  x /= 2

答案 1 :(得分:0)

while (i < 32) { val = (val << 1) | (x & 1); x = x >> 1; i++; }除了val,返回值应该是无符号的,并且它们不在您的模板中。该函数返回x反转的位。

你的问题的实际答案更复杂,而且非常多:没有这样的指南,它不存在,因为编译丢失了信息,你无法从汇编程序中重新创建丢失的信息。但是你经常可以做出好的猜测。