解读汇编代码

时间:2013-11-16 00:49:39

标签: assembly arm

我刚才有几个关于某些助记符含义的问题,以及我给出的代码中存在的命令。我之前从未与大会合作过。

以下是代码片段:

 traverse proc 
      ldr r0, =21475234
      push {r4, r5, lr}
      mov r4, r0
      ldr r5, [r4] 

      ldr r0, [r4, #4]
      bl traverse 
      cmp r5, r0 
      it lt 
      movlt r5, r0 

      mov r0,r5 
      pop {r4,r5,pc}  
  1. 究竟加载到r5的内容是什么?按照说明操作,r4是否被推入堆栈,加载了r0中的值,然后r5也加载了它?

  2. 加载到r0的内容是什么? [r4, #4]是否引用r4中第五个位置的数字?

  3. bl traverse由于我们已经在遍历函数中工作,我们是否将分支链接到同一个函数?

  4. 我不确定pc助记符是什么意思。

  5. proctraverse proc的符号是什么?每个功能声明都需要这个吗?

  6. 先谢谢你们,我还在努力解决这个问题。

1 个答案:

答案 0 :(得分:1)

ldr r0, =21475234

这是一个快捷方式,几乎是伪代码。各种手臂组装者倾向于支持它。

可能打算像这样使用

ldr r0,=hello
ldr r1,[r0]

...

in some other file perhaps

.globl hello
hello:
   .word 0x1234

基本上它意味着在等号后加载东西的地址。

ldr r0,hello
...
hello:
  .word 0x1234

表示将标签hello中的数据值加载到r0。

在C中就是这个

//ldr r0,=hello
unsigned int r0 = (unsigned int)&hello;
//ldr r0,hello
unsigned int r0 = hello;

因为arm大部分是一个固定长度的指令集,其中指令的大小或小于寄存器,当你使用数字作为项目地址而不是标签

ldr r0,=0x12345678

编码为

ldr r0,temp000
...
temp000: .word 0x12345678

将值0x12345678加载到r0中。汇编程序必须找到一个足够接近ldr的位置,但是在执行路径之外放置该数据字,有时你会得到一个无法找到位置的错误。

所以

ldr r0, =21475234

将值21475234加载到r0。

这推动       推{r4,r5,lr} 将r4,r5和返回寄存器lr保存在堆栈中。常用的调用约定对于arm来说你可以销毁r0-r3,但是你必须保留其他寄存器(这里有一个或两个例外)所以要使用r4我们必须保存它。我假设这是编译后的代码而不是手写的和/或是从编译代码中调用的?

所以现在我们可以使用r4,这个值将21475234复制到r4,r0和r4现在保持相同的东西       mov r4,r0 当您将[括号]放在基本上是寄存器间接寻址的寄存器周围时,寄存器的内容不是想要该寄存器的内容,而是您想要的内容的地址,所以这就是读取地址21475234的值并保存r5中的值

  ldr r5, [r4] 

你是否删除了一些代码来发布这个问题?

这表示读取地址21475234 + 4处的值并将其保存在r0

ldr r0, [r4, #4]

当立即值在括号内时,意味着将其添加到寄存器并使用从寄存器r4加4中的地址读取的地址。

ldr r0, [r4, #4]

从添加r4 + r5

生成的地址中读取
ldr r0, [r4, r5]

这与从r4中的地址读取的情况完全不同,将值放在r0 THEN ADD 4到R4中。

ldr r0, [r4], #4

这类似于C代码

unsigned int r0 = *r4++;

lr是链接寄存器r14,pc是程序计数器r15,当你改变r15时它实际上是一个分支。当调用函数(procedure,proc)时,lr的push保存了返回地址,这样你就可以在函数调用之后立即返回运行代码。为了做到这一点,你基本上需要将程序计数器更改为调用后的地址(bl =分支链接,它基本上是对某个地址的函数调用)。因此,你可以推动lr和pop pc,所以这个

pop {r4,r5,pc}

是push的补充,它将r4和r5恢复为输入函数时的值,然后将返回地址弹出到程序计数器中,以使程序分支到该地址。

traverse是过程的标签或名称(函数)proc是过程的缩写。毫无疑问,汇编助记符更专业,而不仅仅是声明标签。标签应该可以正常工作,但如果你这样做,你可以从汇编程序获得更多帮助。 (我从来没有找到理由在20多年的日常集会中做到这一点,但也许其他人都有)。

bl遍历,这是一个递归调用。不知道你是怎么摆脱这个的,你发布了所有的代码吗?