2014-07-16 52 views
0

我想问一下这里的arm指令中发生了什么。我有ASM的知识,但我很难理解ARM。我试图查找互联网上提供基础知识的信息,但我正在看的东西有点不同。所以这里是我想了解的代码..你能解释一下这些指令是做什么的。我会标记那些我不明白的。它是来自IDA的代码。有人可以解释整个功能吗?我会很感激。感谢布尔指令

LDR    R3, =(unk_E9BFB0 - 0x6B1B4C) //This once,i dont get it, is it subtracting? 
LDR    R8, [R5] 
MOV    R1, R6 
ADD    R3, PC, R3 
LDR    LR, [R4,#0xC] //This instruction 
LDR    R12, =(aDraw_debug - 0x6B1B68) //This once 
MOV    R2, R7 
STR    R8, [R3,#0x30] 
MOV    R0, R3 
STR    R4, [R3] 
ADD    R12, PC, R12 ; "draw_debug" //This once 
STR    R3, [R5] 
STR    R12, [R3,#0x2C] 
ADD    R12, LR, #1 
STR    R12, [R4,#0xC] 
BL    __aeabi_atexit 
+0

你尝试ARM的[公司网址](http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0041c/Babbfdih.html)? –

+1

“有人可以解释整个功能吗?”总之,没有。 a)它显然不是一个“完整的函数”,因为最终没有返回,b)它是一系列指令,读取一些内存地址,计算一些偏移量,并写入一些内存地址 - 我非常怀疑任何人都可以解释_why_没有远远超过在这里可能重现的上下文。 – Notlikethat

回答

2

LDR是ARM的指令来加载寄存器与来自存储器的值。下面,但是,都是LDR的pseudoinstruction形式:

LDR    R3, =(unk_E9BFB0 - 0x6B1B4C) //This once,i dont get it, is it subtracting? 
LDR    R12, =(aDraw_debug - 0x6B1B68) //This once 

我相信这是构建从代码位置提取数据出.text部分的偏移量。例如,aDraw_debug - 0x6B1B68很可能取自标签aDraw_debug的地址,并减去某些指令的位置,即0x6B1B68

最终结果是,这基本上会将aDraw_debug(从任意点)的偏移量加载到R12。同样,另一条指令会将unk_E9BFB0加载到R3中。这可能是编译器生成的数据,因为名称是错误的。

其它LDR指令:

LDR    LR, [R4,#0xC] //This instruction 

是一个简单的事情。 LDR仍被用于从内存加载寄存器,但寻址不同。在这种情况下,LR(链接寄存器)正在装入内存中地址为R4 + 0xC的数据。

ADD是简单为好,我不知道,如果你的是困惑,它是做什么,但:

ADD    R12, PC, R12 ; "draw_debug" //This once 

这只是增加了在R12PC + R12并将其存储,而无需更新处理器标志。这将采用先前确定的偏移量并将其应用于当前的PC。总体而言,它看起来像是代码将值存储到某种structclass。编译器选择进行PC相对寻址,但偏移量可能超出指令的可用范围。与PC相关的LDR/STR指令只能从PC得到+/- 4096。

0

ldr reg,=东西是快捷方式。手臂是大多数固定长度的指令集,或者可以说没有足够的位来允许任何可能的立即值。此捷径还允许您使用标签,将某个标签的地址加载到该寄存器中。汇编程序对此的处理是,当它生成机器码时,它会在不太远的地方分配一个不在执行路径中的字位置(例如,在无条件分支或bx之后)。然后,对于ldr reg,=指令,它编码一个pc相关指令ldr reg,[pc,+ offset]将该值加载到寄存器中。这允许加载任何32位值,没有限制。它还允许在链接器稍后填写数据值(地址)的地方使用标签。你的例子进一步考虑了这一点,并在标签上进行了数学运算,因此汇编器或链接器必须解析标签,进行数学运算,然后将该值放入单词位置。