gpt4 book ai didi

c - 这个反汇编如何对应给定的 C 代码?

转载 作者:行者123 更新时间:2023-12-02 08:23:57 26 4
gpt4 key购买 nike

环境:ARM Cortex m4f 的 GCC 4.7.3 (arm-none-eabi-gcc)。裸机(实际上是 MQX RTOS,但在这里无关紧要)。 CPU 处于 Thumb 状态。

这是我正在查看的一些代码的反汇编程序列表:

//.label flash_command
// ...
while(!(FTFE_FSTAT & FTFE_FSTAT_CCIF_MASK)) {}
// Compiles to:
12: bf00 nop
14: f04f 0300 mov.w r3, #0
18: f2c4 0302 movt r3, #16386 ; 0x4002
1c: 781b ldrb r3, [r3, #0]
1e: b2db uxtb r3, r3
20: b2db uxtb r3, r3
22: b25b sxtb r3, r3
24: 2b00 cmp r3, #0
26: daf5 bge.n 14 <flash_command+0x14>

常量(在扩展宏等之后)是:

address of FTFE_FSTAT is 0x40020000u
FTFE_FSTAT_CCIF_MASK is 0x80u

这是在没有优化 (-O0) 的情况下编译的,所以 GCC 不应该做任何花哨的事情...... 然而,我没有得到这段代码。 答案后编辑:永远不要假设这一点。我的问题是关闭优化会产生一种错误的安全感。

我读到“uxtb r3,r3”是截断 32 位值的常用方法。为什么要将其截断两次然后进行符号扩展?这到底是怎么等同于 C 代码中的位掩码操作的呢?

我在这里错过了什么?

编辑:涉及的事物类型:所以 FTFE_FSTAT 的实际宏扩展归结为

((((FTFE_MemMapPtr)0x40020000u))->FSTAT)

结构定义为

/** FTFE - Peripheral register structure */
typedef struct FTFE_MemMap {
uint8_t FSTAT; /**< Flash Status Register, offset: 0x0 */
uint8_t FCNFG; /**< Flash Configuration Register, offset: 0x1 */
//... a bunch of other uint_8
} volatile *FTFE_MemMapPtr;

最佳答案

这两个uxtb 指令是编译器愚蠢的,如果你打开优化,它们应该被优化掉。 sxtb 是出色的编译器,使用了您在未优化代码中不会想到的技巧。

第一个 uxtb 是因为您从内存中加载了一个字节。编译器正在将寄存器 r3 的其他 24 位清零,以便字节值填满整个寄存器。

第二个 uxtb 是因为您要与一个 8 位值进行与运算。编译器意识到结果的高 24 位将始终为零,因此它使用 uxtb 清除高 24 位。

uxtb 指令都没有做任何有用的事情,因为 sxtb 指令无论如何都会覆盖 r3 的高 24 位。优化器应该意识到这一点,并在启用优化的情况下进行编译时将其删除。

sxtb 指令将您关心的一位0x80 移入寄存器r3 的符号位。这样,如果位 0x80 被设置,则 r3 变为负数。所以现在编译器可以与 0 进行比较以确定该位是否已设置。如果该位设置,则bge 指令分支回到while 循环的顶部。

关于c - 这个反汇编如何对应给定的 C 代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34189516/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com