我想问一下这里的手臂指示是怎么回事。我对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 :(得分:2)
LDR
是ARM上用于从内存加载带有值的寄存器的指令。但是,以下是LDR
:
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
这只是添加PC + R12
并将其存储在R12
中而不更新处理器标志。这将获取先前确定的偏移量并将其应用于当前PC
。
总的来说,这似乎是将值存储到某种struct
或class
的代码。编译器选择进行PC相对寻址,但偏移量可能超出指令的可用范围。与PC相关的LDR/STR
指令只能解决PC
中的+/- 4096。
答案 1 :(得分:0)
ldr reg,=某事是捷径。臂是一个大多数固定长度的指令集,或者说没有足够的位来允许任何可能的立即值。此快捷方式还允许您使用标签,将某些标签的地址加载到此寄存器中。汇编器对此做的是当它生成机器代码时,它在不太远的地方分配一个字位置,而不是在执行路径中(例如在无条件分支或bx之后)。然后对于ldr reg,=指令,它编码pc相对指令ldr reg,[pc,+ offset]以将该值加载到寄存器中。这允许加载任何32位值,没有限制。它还允许在链接器稍后填充数据值(地址)的地方使用标签。你的例子更进一步,并在标签上进行数学运算,因此汇编器或链接器必须解析标签,进行数学计算,然后将该值放在单词位置。
答案 2 :(得分:0)