ldr [pc, #value] 的奇怪行为 [英] Strange behaviour of ldr [pc, #value]

查看:21
本文介绍了ldr [pc, #value] 的奇怪行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在调试一些 C++ 代码(ARM 平台上的 WinCE 6),我发现有些行为很奇怪:

I was debugging some c++ code (WinCE 6 on ARM platform), and i find some behavior strange:

    4277220C    mov         r3, #0x93, 30
    42772210    str         r3, [sp]
    42772214    ldr         r3, [pc, #0x69C]
    42772218    ldr         r2, [pc, #0x694]
    4277221C    mov         r1, #0
    42772220    ldr         r0, [pc, #0x688]

42772214 ldr r3, [pc, #0x69C] 用于从 .DATA 部分获取一些常量,至少我是这么认为的.

Line 42772214 ldr r3, [pc, #0x69C] is used to get some constant from .DATA section, at least I think so.

奇怪的是,根据代码 r2 应该从地址 pc=0x42772214 + 0x69C = 0x427728B0 填充内存,但根据它从 0x427728B8 (8bytes+) 加载的内存内容,其他 ldr 用法也会发生这种情况.

What is strange that according to the code r2 should be filled with memory from address pc=0x42772214 + 0x69C = 0x427728B0, but according to the memory contents it's loaded from 0x427728B8 (8bytes+), it happens for other ldr usages too.

是调试器的问题还是我对ldr/pc的理解?我不明白的另一个问题 - 为什么对 .data 部分的访问与执行的代码有关?我觉得有点奇怪.

Is it fault of the debugger or my understanding of ldr/pc? Another issue I don't get - why access to the .data section is relative to the executed code? I find it little bit strange.

还有一个问题:我找不到第一个 mov 命令的语法(任何人都可以向我指出 Thumb (1C2) 的 optype 规范)

And one more issue: i cannot find syntax of the 1st mov command (any one could point me a optype specification for the Thumb (1C2))

抱歉我的描述不准确,但我只是熟悉程序集.

Sorry for the laic description, but I'm just familiarizing with the assemblies.

推荐答案

这是正确的.当pc用于读取时,ARM模式下有8个字节的偏移量,Thumb模式下有4个字节的偏移量.

This is correct. When pc is used for reading there is an 8-byte offset in ARM mode and 4-byte offset in Thumb mode.

来自 ARM-ARM:

From the ARM-ARM:

当一条指令读取PC时,读取的值取决于它来自哪个指令集:

When an instruction reads the PC, the value read depends on which instruction set it comes from:

  • 对于 ARM 指令,读取的值是指令地址加上 8 个字节.此值的位 [1:0] 始终为零,因为 ARM 指令始终是字对齐的.
  • 对于 Thumb 指令,读取的值是指令地址加上 4 个字节.该值的位 [0] 始终为零,因为 Thumb 指令始终是半字对齐的.
  • For an ARM instruction, the value read is the address of the instruction plus 8 bytes. Bits [1:0] of this value are always zero, because ARM instructions are always word-aligned.
  • For a Thumb instruction, the value read is the address of the instruction plus 4 bytes. Bit [0] of this value is always zero, because Thumb instructions are always halfword-aligned.

这种读取 PC 的方式主要用于对附近指令和数据进行快速、与位置无关的寻址,包括程序内与位置无关的分支.

This way of reading the PC is primarily used for quick, position-independent addressing of nearby instructions and data, including position-independent branching within a program.

PC 相对寻址有两个原因.

There are 2 reasons for pc-relative addressing.

  1. 与位置无关的代码,适合您的情况.
  2. 在附近获取一些不能用 1 条简单指令编写的复杂常量,例如mov r3, #0x12345678 不可能在 1 条指令中完成,因此编译器可能会将这个常量放在函数的末尾并使用例如ldr r3, [pc, #0x50] 改为加载它.
  1. Position-independent code, which is in your case.
  2. Get some complicated constants nearby which cannot be written in 1 simple instruction, e.g. mov r3, #0x12345678 is impossible to complete in 1 instruction, so the compiler may put this constant in the end of the function and use e.g. ldr r3, [pc, #0x50] to load it instead.


我不知道 mov r3, #0x93, 30 是什么意思.可能是 mov r3, #0x93, rol 30 (它给出 0xC0000024)?


I don't know what mov r3, #0x93, 30 means. Probably it is mov r3, #0x93, rol 30 (which gives 0xC0000024)?

这篇关于ldr [pc, #value] 的奇怪行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆