去尝试一下...
所以.s
.thumb
sub r0,#1
.syntax unified
subs r0,r0,#1
sub r0,#1
subs.n r0,#1
组装和拆卸
arm-none-eabi-as so.s -o so.o
arm-none-eabi-objdump -D so.o
so.o: file format elf32-littlearm
Disassembly of section .text:
00000000 <.text>:
0: 3801 subs r0, #1
2: 3801 subs r0, #1
4: f1a0 0001 sub.w r0, r0, #1
8: 3801 subs r0, #1
编辑奥拉夫的评论。
.thumb
sub r0,#1
sub r0,r0,#1
sub r1,r2,#1
.syntax unified
subs r0,r0,#1
sub r0,#1
subs.n r0,#1
subs.n r0,r0,#1
subs r1,r2,#1
00000000 <.text>:
0: 3801 subs r0, #1
2: 3801 subs r0, #1
4: 1e51 subs r1, r2, #1
6: 3801 subs r0, #1
8: f1a0 0001 sub.w r0, r0, #1
c: 3801 subs r0, #1
e: 3801 subs r0, #1
10: 1e51 subs r1, r2, #1
我/你/我们将不得不深入研究汇编源代码,看看是否有办法解决这个问题。Fuz 可能有最简单的答案。很可能,汇编程序立即优化为具有更大灵活性的汇编程序。您当然可以删除该优化/功能(如果没有标志)。
编辑2
也许就是这样。
#define T_OPCODE_SUB_I8 0x3800
#define T_OPCODE_SUB_I3 0x1e00
else if (rs == rd)
{
if (value & ~0xff)
as_bad_where (fixP->fx_file, fixP->fx_line,
_("immediate value out of range"));
newval = subtract ? T_OPCODE_SUB_I8 : T_OPCODE_ADD_I8;
newval |= (rd << 8) | value;
}
else
{
if (value & ~0x7)
as_bad_where (fixP->fx_file, fixP->fx_line,
_("immediate value out of range"));
newval = subtract ? T_OPCODE_SUB_I3 : T_OPCODE_ADD_I3;
newval |= rd | (rs << 3) | (value << 6);
}
如果你添加这个
else if (value & ~0x7)
{
newval = subtract ? T_OPCODE_SUB_I3 : T_OPCODE_ADD_I3;
newval |= rd | (rs << 3) | (value << 6);
}
在...前面
else if (rs == rd)
然后
.cpu cortex-m7
.thumb
sub r0,r0,#15
sub r0,r0,#1
.syntax unified
subs.n r0,r0,#1
subs.n r0,r0,#15
给出了想要的结果。
0: 1fc0 subs r0, r0, #7
2: 3801 subs r0, #1
4: 3801 subs r0, #1
6: 1fc0 subs r0, r0, #7
所以我认为 rs == rd 会阻止你生成你想要的指令。
编辑 3
binutils 2.7 没有这个定义 T_OPCODE_SUB_I8 所以可能没有拇指支持,没有比这更深入。binutils 2.8 做了并且也包括了这个优化。早在 1997 年,这种情况就已经存在。如果您想使用 gnu 汇编器生成相关指令,您似乎需要修改 gnu 汇编器...