【问题标题】:A reference for converting assembly 'shl', 'OR', 'AND', 'SHR' operations into C?将程序集“shl”、“OR”、“AND”、“SHR”操作转换为 C 的参考?
【发布时间】:2018-07-17 13:46:11
【问题描述】:

我要将以下 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;
}

我可以看出sn-p

.L2
  cmpl $32, %ecx
  jl   .L1

可以解释为while(i<32)。我也知道x存储在%edx中,val存储在%eax中,i存储在%ecx中。但是,我很难将while/.L1 循环中的程序集转换为适合提供的骨架代码的浓缩高级语言。例如,shllshrlorlandl 是否可以简单地使用它们的直接 C 等效项 (<<,>>,|,&) 编写,或者有一些更细微的差别?

是否有用于汇编到 C 转换的标准化指南/“备忘单”?

我知道汇编到高级别的转换并不总是一目了然,但汇编代码中肯定有一些模式可以一致地解释为某些 C 操作。

【问题讨论】:

标签: c assembly reverse-engineering att


【解决方案1】:

例如,shll、shrl、orl 和 andl 可以简单地写成 它们的直接 C 等价物(>,|,&),还是有更多细微差别 给它?

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

  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

combine a,b,c: #2 insert a into b:

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

combine a,b,c: #2 insert b into c:

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

最后一步:将两个 'val =' 合二为一

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

【讨论】:

  • 很好的解释。现在很容易理解!我没想到这么简单。请随意忽略下一个问题,但我现在被要求“用英语描述函数 f 计算的内容:”并且想知道您是否碰巧立即认识到该函数在外行的术语中正在做什么。
  • 一个寄存器左移 32 次,另一个寄存器右移。我的猜测是这个函数颠倒了 x 位的顺序
【解决方案2】:

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

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

【讨论】:

    猜你喜欢
    • 2020-07-24
    • 1970-01-01
    • 2010-11-17
    • 1970-01-01
    • 2021-09-13
    • 2013-07-14
    • 2014-01-24
    • 1970-01-01
    相关资源
    最近更新 更多