ARM中LDR指令右侧的等号=代表将所加载的值存储到指定的地址中。

22

我已经搜索了一段时间,但是找不到任何关于这个的文档。我一直在尝试学习ARM,并查看编译后的ARM汇编代码以了解我编写的一个简单计算器.c程序中发生了什么。我一直看到的东西是像这样的指令:

LDR     R3, =__stack_chk_guard__GLIBC_2.4

或者

LDR     R0, =aEnterOperator ; "Enter operator: "
或者
LDR     R0, =aSIsNotAValidOp ; "%s is not a valid operator.  Enter +, -"
注意:分号后面的内容只是IDA自动添加的注释。
我的问题是,这些LDR指令右侧的'='符号代表什么?在第一个情况中,它似乎是指示加载库的标记; 在第二个和第三个情况中,'=a'似乎是在printf前缀。 我不太确定这是什么意思,因为我在文档中找不到关于LDR语法的任何信息。 有人能帮我理解吗?谢谢!

你使用哪个汇编器?你有阅读过汇编器的文档吗? - too honest for this site
相关:https://dev59.com/3mQm5IYBdhLWcg3w8iuD - Ciro Santilli OurBigBook.com
2个回答

28
在LDR指令的第二个操作数的开头使用等号(=)表示使用LDR伪指令。尽管ARM指令集仅支持非常小范围内的立即值,但该伪指令用于将任意32位常量值加载到一个寄存器中,只需一条指令即可完成。
如果“=”后面的值由汇编器知道并符合MOV或MVN指令的允许范围,则会生成MOV或MVN指令。否则,常量值将被放入文字池中,并使用相对于PC的LDR指令将该值加载到寄存器中。
如果Ida在反汇编代码时生成这些LDR=指令,则必须检测到汇编器或编译器选择生成代码时选择了第二个选项。实际指令类似于LDR R0, loc_1234567(更准确地说是LDR R0, [PC, #-1234]),而Ida会为您查阅文字池中loc_1234567处的值。

5

=通常后面跟随着一个即时数值,并指示汇编器将该常数放置于附近的字面池中,并生成一个pc相对内存操作数来加载它。这很有用,因为ARM指令格式没有足够的空间来存储完整的32位常数。从附近的字面池中加载无法用8位(我认为)加上移位编码的常数是一种有效和高效的绕过此问题的方法。


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