简体   繁体   English

这种反汇编如何与给定的C代码相对应?

[英]How does this disassembly correspond to the given C code?

Environment: GCC 4.7.3 (arm-none-eabi-gcc) for ARM Cortex m4f. 环境:适用于ARM Cortex m4f的GCC 4.7.3(arm-none-eabi-gcc)。 Bare-metal (actually MQX RTOS, but here that's irrelevant). 裸机(实际上是MQX RTOS,但这无关紧要)。 The CPU is in Thumb state. CPU处于Thumb状态。

Here's a disassembler listing of some code I'm looking at: 这是我正在查看的一些代码的反汇编程序列表:

//.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>

The constants (after expending macros, etc.) are: 常量(在扩展宏等之后)是:

address of FTFE_FSTAT is 0x40020000u
FTFE_FSTAT_CCIF_MASK is 0x80u

This is compiled with NO optimization (-O0), so GCC shouldn't be doing anything fancy... and yet, I don't get this code. 这是使用NO优化(-O0)进行编译的,因此GCC不应做任何花哨的事情...但是,我没有得到此代码。 Post-answer edit: Never assume this. 答案后编辑:永远不要做这个。 My problem was getting a false sense of security from turning off optimization. 我的问题是关闭优化后会产生一种错误的安全感。

I've read that "uxtb r3,r3" is a common way of truncating a 32-bit value. 我读过“ uxtb r3,r3”是截断32位值的常用方法。 Why would you want to truncate it twice and then sign-extend? 为什么要截断两次然后进行符号扩展? And how in the world is this equivalent to the bit-masking operation in the C-code? 到底这与C代码中的位屏蔽操作等效吗?

What am I missing here? 我在这里想念什么?

Edit: Types of the thing involved: So the actual macro expansion of FTFE_FSTAT comes down to 编辑:涉及的事物的类型:因此FTFE_FSTAT的实际宏扩展可以归结为

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

where the struct is defined as 结构定义为

/** 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;

The two uxtb instructions are the compiler being stupid, they should be optimized out if you turn on optimization. 两条uxtb指令是愚蠢的编译器,如果您打开优化功能,则应该对其进行优化。 The sxtb is the compiler being brilliant, using a trick that you wouldn't expect in unoptimized code. sxtb是一种出色的编译器,它使用了在未优化的代码中不会出现的技巧。

The first uxtb is due to the fact that you loaded a byte from memory. 第一个uxtb是由于您从内存中加载了一个字节。 The compiler is zeroing the other 24 bits of register r3, so that the byte value fills the entire register. 编译器会将寄存器r3的其他24位清零,以便字节值填满整个寄存器。

The second uxtb is due to the fact that you're ANDing with an 8-bit value. 第二个uxtb是由于您要与8位值进行“与” uxtb The compiler realizes that the upper 24-bits of the result will always be zero, so it's using uxtb to clear the upper 24-bits. 编译器意识到结果的高24位始终为零,因此它使用uxtb清除高24位。

Neither of the uxtb instructions does anything useful, because the sxtb instruction overwrites the upper 24 bits of r3 anyways. uxtb指令都没有任何用处,因为sxtb指令无论如何sxtb覆盖r3的高24位。 The optimizer should realize that and remove them when you compile with optimizations enabled. 在启用优化的情况下进行编译时,优化器应意识到并删除它们。

The sxtb instruction takes the one bit you care about 0x80 and moves it into the sign bit of register r3 . sxtb指令将您关心的一位0x80移到寄存器r3的符号位。 That way, if bit 0x80 is set, then r3 becomes a negative number. 这样,如果将位0x80置1,则r3变为负数。 So now the compiler can compare with 0 to determine whether the bit was set. 因此,现在编译器可以将其与0进行比较,以确定是否设置了该位。 If the bit was not set then the bge instruction branches back to the top of the while loop. 如果设置该位,则bge指令分支回到while循环的顶部。

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

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