谷歌搜索了一段时间,但我找不到任何与此有关的文件.我一直在努力学习ARM并且一直在查看已编译的ARM汇编代码以获得我编写的一个简单的calculator.c程序,以便了解我是否能够理解发生了什么.我一直看到的是这样的指示:
LDR R3, =__stack_chk_guard__GLIBC_2.4
Run Code Online (Sandbox Code Playgroud)
要么
LDR R0, =aEnterOperator ; "Enter operator: "
Run Code Online (Sandbox Code Playgroud)
要么
LDR R0, =aSIsNotAValidOp ; "%s is not a valid operator. Enter +, -"
Run Code Online (Sandbox Code Playgroud)
注意:分号后面的内容只是IDA添加的自动注释.
我的问题是,这些LDR右侧的"="是什么意思?在第一种情况下,它似乎是一些标记指示库的加载; 在第二和第三种情况下,'= a'似乎是一个printf的前面.我只是不太确定这个,因为我在文档中找不到任何关于LDR的语法.有人能帮助我理解这个吗?谢谢!
Ros*_*dge 14
在LDR指令的第二个操作数的开始处使用等号(=)表示使用LDR伪指令.尽管ARM指令集仅支持更小范围内的立即值,但该pseuo指令用于将任意32位常量值加载到具有单个指令的寄存器中.
如果=汇编器知道后面的值并且符合MOV或MVN指令的立即值的允许范围,则生成MOV或MVN指令.否则,将常量值放入文字池中,并使用PC相对LDR指令将值加载到寄存器中.
如果Ida在反汇编代码时生成这些LDR =指令,则它必须检测到汇编器或编译器在生成您正在查看的代码时选择了第二个选项.实际的指令就像是LDR R0, loc_1234567(或更准确地说是类似的东西LDR R0, [PC, #-1234]),Ida正在loc_1234567为你查找文字池中的值.
=通常以立即常量为后缀,指示汇编器将该常量放入附近的文字池中,并生成一个pc相对内存操作数来加载它。这很有用,因为 ARM 指令格式没有足够的空间来存储完整的 32 位常量。加载无法以 8 位编码的常量(我认为)加上从附近文字池的移位是规避此问题的有效且高效的方法。