我在任何地方都找不到这个问题的直接答案。 ARM的寄存器是32位的,我知道LDRB将一个字节大小的值加载到寄存器中,并将剩余的3个字节清零,即使你给它提供一个大于一个字节的值,它也只会取第一个字节的值。
我的程序将 C 与 ARM 汇编相结合。我在 C 中有一个外部变量,它直接加载到寄存器中。
但是,如果我在这个字节变量上只调用 LDR,是否可以保证它加载该字节而不加载其他内容,或者它会从内存中附近的内容加载剩余 3 个字节空间中的随机内容以填充整个 32-位寄存器?
我只是问,因为我执行了 LDR R0, =var 并且总是从大约一亿次执行中得到正确的值(软件运行了很长时间,并且在提出此问题之前经过了多次彻底测试/重新编译)在另一个设置上)。
然而,其他人使用不同的设置(没那么不同,我认为编译器是同一版本)成功编译了代码,但是加载到 R0 中的值被变量周围内存中的随机位污染了。他们必须使用 LDRB 来修复它。
这是编译器的事情吗?它能检测到这一点并自动切换到 LDRB 吗?或者我只是幸运的是,由于某些优化,变量的周围内存只是零?
顺便说明一下,编译器是 ARM GCC 9.2.1
最佳答案
because I did
LDR R0, =var
您正在加载变量的值还是地址?
通常,指令LDR R0, =var
会将变量var
的地址写入寄存器R0
,而不是值。
在 32 位 ARM CPU 上,变量的地址始终是 32 位值 - 与数据类型无关。
However if I call just
LDR
on this byte variable, ...
如果加载变量的值(例如使用LDR R1, [R0]
),可能会发生两种情况:
- 寄存器的高 24 位可能包含随机值,具体取决于内存中变量后面的字节。如果幸运的话,字节始终为零。
- 根据具体的 CPU 类型,您可能会因对齐而遇到问题(例如对齐异常,甚至完全未定义的行为)
关于c - ARM 中 uint8_t 变量上的 LDR 行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59915224/