为 ARM (windows) 使用 GCC 编译器:
arm-none-eabi-gcc.exe (Sourcery CodeBench Lite 2012.09-63) 4.7.2 version
我每编译同一个源文件大约 5 次就会生成不同的目标文件。
使用优化级别 3(激进),使用编译器选项:
-O3 -mcpu=cortex-a8 -mfpu=neon -mfloat-abi=softfp -fshort-wchar -fshort-enums -funsafe-math-optimizations -mvectorize-with-neon-quad
不同目标文件的转储(使用 objdump)显示汇编指令、寄存器和使用的地址存在太多差异。
编译器优化/编译完全相同的源是否正常 不同的文件并产生不同的目标文件?!是编译器错误吗?
如何在不关闭攻击性的情况下避免这种行为 优化 ?
编辑: 目标文件差异片段:
object_file_dump_A:
0000350 <PreInit>:
350: e3003000 movw r3, #0
354: e3403000 movt r3, #0
358: e92d4ff0 push {r4, r5, r6, r7, r8, r9, sl, fp, lr}
35c: e1a09000 mov r9, r0
360: e24dd034 sub sp, sp, #52 ; 0x34
/*some identical ASM for both files */
388: e1a0700b mov r7, fp
38c: e1a0600b mov r6, fp
390: e300a000 movw sl, #0
394: e340a000 movt sl, #0
398: e5911004 ldr r1, [r1, #4]
39c: e8ae0003 stmia lr!, {r0, r1}
object_file_dump_B:
00000350 <PreInit>:
350: e3003000 movw r3, #0
354: e3403000 movt r3, #0
358: e92d4ff0 push {r4, r5, r6, r7, r8, r9, sl, fp, lr}
35c: e1a08000 mov r8, r0
360: e24dd034 sub sp, sp, #52 ; 0x34
/*some identical ASM for both files */
388: e1a0700b mov r7, fp
38c: e3009000 movw r9, #0
390: e3409000 movt r9, #0
394: e5911004 ldr r1, [r1, #4]
398: e8ae0003 stmia lr!, {r0, r1}
39c: e5b30010 ldr r0, [r3, #16]!
编辑:
源代码:
void PreInit(init_T *f_params, results_T *results)
{
u8 i, j, k, idx;
const u8 cr_index[4] = {0, 1, 2, 7};
const u8 minVal[] = {2, 4, 6, 0, 0, 0, 0, 19};
const u8 maxVal[] = {0, 3, 5, 0, 0, 0, 0, 18};
memset(f_params, 0, sizeof(init_T));
_ASSERT(CONF_NUM_X_LIMITS == CST_NbSLi);
_ASSERT(CONF_NUM_CRITERIA == CST_NbIdxCriteria);
for (i = 0; i < CST_NbSLi; ++i)
{
f_params->_sli[i].x = s_limits[i];
for (j = 0; j < CST_NbIdxCriteria; ++j)
{
f_params->_sli[i].criteria[j] = conf_criterias[i][j];
}
}
/*some code*/
}
最佳答案
正如其他人所提到的,汇编代码是等效的。 如果你仔细观察它们,命令
e1a0600b mov r6, fp
它将fp移动到r6,但是r6寄存器后面没有用到。 因此,如果我们考虑分配寄存器的随机化策略和代码创建,则变化不大,并且在第二部分中优化删除了该行。
关于c - gcc-arm编译器为同一个源文件生成不同的目标文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17067763/