在编译ARM指令时,有些指令会因为指令模式不同而编译出错
有如下指令,该指令会对寄存器值进行移位操作,在ARM-v8手册里描述只支持A1模式(ARM模式)
void adc_ins(void)
{
int en1 = 10;
int en2 = 9;
int en3 = 1;
int re1;
__asm__ __volatile__(
"ADC %0, %1, %2, LSL %3"
: "=r"(re1)
: "r"(en1),"r"(en2),"r"(en3)
:
);
}
当直接使用ARM-v8的编译工具进行编译时会出错,因为编译时默认选择的是Thumb指令模式
$ armv8l-linux-gnueabihf-gcc adc.c
/tmp/ccDdJFZP.s: Assembler messages:
/tmp/ccDdJFZP.s:39: Error: shift must be constant -- `adc r3,r3,r2,LSL r1'
由于该指令只支持ARM模式,所以在编译时需要加上参数-marm来切换ARM模式编译才能正常编译出指令
armv8l-linux-gnueabihf-gcc -marm adc.c
查看反汇编可以看到指令编码是32位的,与上图对应
103d0: e0a33112 adc r3, r3, r2, lsl r1
下面来测试下能同时支持ARM和Thumb的指令,这条指令是ADC对立即数的操作,
void adc_ins(void)
{
int en1 = 10;
int re1;
__asm__ __volatile__(
"ADC %0, %1, #5"
: "=r"(re1)
: "r"(en1)
);
}
分别用两种模式来进行编译
ARM模式:
103b8: e2a33005 adc r3, r3, #5
Thumb模式:
103ac: f143 0305 adc.w r3, r3, #5
可以看到编译出的指令码是不同的