【发布时间】:2017-05-26 19:20:49
【问题描述】:
我想知道为什么不同的编译器使用不同的汇编指令。
例如,我使用 TI 的 cc3200,它内部有 Cortex-M4,这是来自 SDK 的一段真实代码:
#if defined(ewarm)
#define BACK_UP_ARM_REGISTERS() { \
__asm(" push {r0-r12,LR} \n" \
" mov32 r1, vault_arm_registers \n" \
" mrs r0,msp \n" \
" str r0,[r1] \n" \
" mrs r0,psp \n" \
" str r0,[r1, #4] \n" \
" mrs r0,primask \n" \
" str r0,[r1, #12] \n" \
" mrs r0,faultmask \n" \
" str r0,[r1, #16] \n" \
" mrs r0,basepri \n" \
" str r0,[r1, #20] \n" \
" mrs r0,control \n" \
" str r0,[r1, #24] \n"); \
}
#endif
#if defined(ccs)
#define BACK_UP_ARM_REGISTERS() { \
__asm(" push {r0-r12,LR} \n" \
" movw r1, vault_arm_registers \n" \
" movt r1, vault_arm_registers \n" \
" mrs r0,msp \n" \
" str r0,[r1] \n" \
" mrs r0,psp \n" \
" str r0,[r1, #4] \n" \
" mrs r0,primask \n" \
" str r0,[r1, #12] \n" \
" mrs r0,faultmask \n" \
" str r0,[r1, #16] \n" \
" mrs r0,basepri \n" \
" str r0,[r1, #20] \n" \
" mrs r0,control \n" \
" str r0,[r1, #24] \n"); \
}
#endif
如您所见,这两个宏有不同的指令将 32 位移入寄存器。 CCS 支持两条 16 位指令 movw 和 movt,而 EWARM --- 一条用于 32 位移动 mov32。根据经验,我发现 GCC 都不支持它们(实际上它支持movw 和movt,但由于错误constant expression required,此代码无法编译)。所以问题是为什么会这样?我认为指令集对于处理器是固定的。此外,我找不到特定于 GCC、EWARM 或 CCS 的 cortex-m4 指令,我该如何揭示它们?
【问题讨论】:
-
指令集由硬件固定,但编译器可以使用他们想要的任何指令格式。并且不必支持所有的处理器变体。不了解 ARM,但对于 x86 处理器,除非您明确要求,否则 gcc 不会使用 Intel 的汇编格式。
-
不知道 mov32 是什么,这可能是拇指模式与手臂模式,但推送看起来不对。
-
汇编语言是由汇编器定义的,即解析ascii文件的程序,所以需要将汇编语言与汇编器(工具链)相匹配。然后当然内联汇编增加了一个全新的痛苦水平。 (并且是特定于编译器的)。所以 gcc/gas (gnu) 不支持其他一些编译器或汇编语言也就不足为奇了。
-
所以如果你想使用 ti 代码,你可能需要留在 ti 的沙箱中。