将ARM转换为C

3

例如,考虑以下ARM汇编代码,是否有直接将其转换为C语言的简单方法,使用适当的变量名?

      ADD $2  $0  #9
      ADD $3  $0  #3
      ADD $1  $0  $0
loop: ADD $1  $1  #1
      ADD $3  $0  $3, LSL #1
      SUB $2  $2  $1
      CMP $2  $1  
      BNE loop

另外,由于我仍在学习ARM,例如SUB或ADD循环将执行多少次?有没有简单的方法来确定这一点?

感谢您的帮助!除了回答问题之外的任何其他见解也非常好。


1
你要找的是叫做C反编译器。 - m0skit0
2个回答

3
简而言之,BNE - 不相等分支,可能是指 do{...}while 循环或者另一种方式的 while (...){...} 循环,甚至可能是一个 for( ...; ... < ....; ...){...} 循环,就到这里了。
至于从某些寄存器中读取加减法(在C的上下文中读取,内存变量),您需要通过阅读它并提出一个相近的等效方法来完成。
在这个阶段,反编译程序可能没有帮助,您可以尝试使用一些C代码进行练习,并使用传递给C编译器的 -S 命令参数将其编译为汇编语言,看看你得到了什么结果。大部分时候都是试错,这取决于您是否在寻找以上问题中代码的精确复制品。

那么没有办法逐行执行上述代码吗?并非所有ARM的指令都可以直接转换为可转换为C的内容? - Bob John
添加和减去可能建议使用C语言中的+++=-=甚至是--(增量和减量,以及简写的加法/减法)运算符...这取决于ARM代码本身的上下文,比如它做什么..? - t0mm13b
1
@BobJohn 是的,很可能可以逐行将汇编代码翻译成C语言。但是在你完成这个过程之后,通常更有意义的是开始识别表明更高级逻辑的模式,例如增量/减量运算符、while或者甚至for循环等。 - Theodoros Chatzigiannakis

1
unsigned int r0,r1,r2,r3;

r2=r0+9;
r3=r0+3;
r1=r0+r0;
do 
{
  r1=r1+1;
  r3=r0+(r3<<1);
  r2=r2-r1;
} while(r2!=r1);

在循环中不知道r0是什么可能会发生几次或者很多次(像百万?十亿?)r2在减小,r1在增加,如果它们第一次通过时没有与等号相撞,它们将不得不绕回来。每个循环r1都会变大,所以r2会更快地变小。应该很容易添加printf和一些测试值来测试r0并查看发生了什么。

例如,假设r0在进入此代码之前为0。r2是r0 + 9 = 9;r1是r0的两倍,即0。

前面几个循环将使用四个变量r0、r1、r2、r3进行如下操作:

00000000 00000001 00000008 00000006
00000000 00000002 00000007 0000000C
00000000 00000003 00000006 00000018
00000000 00000004 00000005 00000030
00000000 00000005 00000004 00000060
00000000 00000006 00000003 000000C0
00000000 00000007 00000002 00000180
00000000 00000008 00000001 00000300
00000000 00000009 00000000 00000600
00000000 0000000A FFFFFFFF 00000C00
00000000 0000000B FFFFFFFE 00001800

r2和r1不会发生碰撞。

但是如果r0是一个1进入的话

00000001 00000003 00000009 00000009
00000001 00000004 00000008 00000013
00000001 00000005 00000007 00000027
00000001 00000006 00000006 0000004F

r0 = 3

00000003 00000007 0000000B 0000000F
00000003 00000008 0000000A 00000021
00000003 00000009 00000009 00000045

r0目前需要是奇数。但当你将r0设为9时,

00000009 00000013 00000011 00000021
00000009 00000014 00000010 0000004B
00000009 00000015 0000000F 0000009F
00000009 00000016 0000000E 00000147
00000009 00000017 0000000D 00000297
00000009 00000018 0000000C 00000537
00000009 00000019 0000000B 00000A77
00000009 0000001A 0000000A 000014F7
00000009 0000001B 00000009 000029F7
00000009 0000001C 00000008 000053F7
00000009 0000001D 00000007 0000A7F7
00000009 0000001E 00000006 00014FF7
00000009 0000001F 00000005 00029FF7
00000009 00000020 00000004 00053FF7
00000009 00000021 00000003 000A7FF7
00000009 00000022 00000002 0014FFF7
00000009 00000023 00000001 0029FFF7
00000009 00000024 00000000 0053FFF7
00000009 00000025 FFFFFFFF 00A7FFF7
00000009 00000026 FFFFFFFE 014FFFF7

基本上这是一个有一些规则的小决定性程序,但如果比较不发生,则循环可能会永远运行,或者至少有很多个周期。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接