简体   繁体   English

ARM中LDR指令右侧的等号=是什么意思?

[英]What does an equals sign = on the right side of a LDR instruction in ARM mean?

Been googling this for a while but i can't find any documentation relating to this. 谷歌搜索了一段时间,但我找不到与此有关的任何文档。 I've been trying to learn ARM and have been looking at the compiled ARM assembly code for a simple calculator.c program i wrote in order to see if I could understand what was going on. 我一直在尝试学习ARM,并一直在寻找我编写的简单的Calculator.c程序的已编译ARM汇编代码,以查看是否可以理解发生了什么。 The thing I keep seeing is instructions like these: 我不断看到的是这样的指令:

LDR     R3, =__stack_chk_guard__GLIBC_2.4

or 要么

LDR     R0, =aEnterOperator ; "Enter operator: "

or 要么

LDR     R0, =aSIsNotAValidOp ; "%s is not a valid operator.  Enter +, -"

Note: the stuff after the semicolons is just the auto-comments added by IDA. 注意:分号后面的内容只是IDA添加的自动注释。

My question is, what does the '=' on the right side of these LDRs mean? 我的问题是,这些LDR右侧的'='是什么意思? In the first case, it seems to be some tag indicating the loading of a library; 在第一种情况下,它似乎是一个指示库加载的标签; in the second and third cases, '=a' seems to be prefacing a printf. 在第二和第三种情况下,'= a'似乎在printf的开头。 I'm just not quite sure to make of this, since I can't find anything about this syntax for LDR in the documentation. 我只是不太确定要这样做,因为在文档中找不到有关LDR的这种语法的任何信息。 Can someone help me understand this? 有人可以帮我理解吗? Thank you! 谢谢!

The use of an equals sign (=) at the start of the second operand of the LDR instruction indicates the use of the LDR pseudo-instruction . 在LDR指令的第二个操作数的开头使用等号(=)表示使用LDR伪指令 This pseuo-instruction is used to load an arbitrary 32-bit constant value into a register with a single instruction despite the fact that the ARM instruction set only supports immediate values in a much smaller range. 尽管ARM指令集仅支持较小范围内的立即数,但该伪指令用于通过一条指令将任意32位常数值加载到寄存器中。

If the value after the = is known by the assembler and fits in with the allowed range of an immediate value for the MOV or MVN instruction then a MOV or MVN instruction is generated. 如果汇编器已知=之后的值,并且该值适合MOV或MVN指令的立即数的允许范围,则将生成MOV或MVN指令。 Otherwise the constant value is put into the literal pool, and a PC-relative LDR instruction is used to load the value into the register. 否则,将常量值放入文字池中,并使用PC相对LDR指令将值加载到寄存器中。

If Ida is generating these LDR= instructions when dissassembling code then it must have detected that the assembler or compiler chose the second option when generating the code you're looking at. 如果Ida在反汇编代码时正在生成这些LDR =指令,则它必须已检测到在生成要查看的代码时,汇编程序或编译器选择了第二个选项。 The actual instruction is something like LDR R0, loc_1234567 (or more accurately something like LDR R0, [PC, #-1234] ) and Ida is looking up the value in the literal pool at loc_1234567 for you. 实际的指令类似于LDR R0, loc_1234567 (或更准确地说,类似于LDR R0, [PC, #-1234] ),而Ida正在为您查找文字池中loc_1234567的值。

= is usually suffixed by an immediate constant and instructs the assembler to put the constant into a nearby literal pool and generate a pc relative memory operand to load it. =通常以立即数作为后缀,并指示汇编程序将常数放入附近的文字池中,并生成pc相对内存操作数以将其加载。 This is useful since the ARM instruction format doesn't have enough space to store a full 32 bit constant. 这很有用,因为ARM指令格式没有足够的空间来存储完整的32位常量。 Loading constants that cannot be encoded in 8 bits (I think) plus a shift from a nearby literal pool is an effective and efficient way to circumvent this problem. 加载无法以8位编码的常量(我认为)加上从附近的文字池中移出的常量是避免此问题的有效方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM