[英]How does this disassembly correspond to the given C code?
环境:适用于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
这是使用NO优化(-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位值进行“与” uxtb
。 编译器意识到结果的高24位始终为零,因此它使用uxtb
清除高24位。
uxtb
指令都没有任何用处,因为sxtb
指令无论如何sxtb
覆盖r3
的高24位。 在启用优化的情况下进行编译时,优化器应意识到并删除它们。
sxtb
指令将您关心的一位0x80
移到寄存器r3
的符号位。 这样,如果将位0x80
置1,则r3
变为负数。 因此,现在编译器可以将其与0
进行比较,以确定是否设置了该位。 如果未设置该位,则bge
指令分支回到while
循环的顶部。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.