关于sw5cc的inline-asm定义%=的问题
-
刚刚发现sw5cc的
%=
是不管用的, 会在生成的汇编里仍然是%=
, 而不是一个无冲突的标签.
比如:asm volatile("ldi %0, -5($31)\n\t" "ldi %1, 0($31)\n\t" "ale0%=:\n\t" "ldi %0, 1(%0)\n\t" "ldi %1, 1(%1)\n\t" "ble %0, ale0%=\n\t" : "=r"(a), "=r"(b));
应生成(使用gcc -S确实能生成, 虽然过不了汇编器):
ldi %rdx, -5($31) ldi %rax, 0($31) ale08: ldi %rdx, 1(%rdx) ldi %rax, 1(%rax) ble %rdx, ale08
其中
%=
被替换成了一个唯一index. 至于%rdx
啥的是因为寄存器号是x86格式.
而sw5cc不会替换%=
:ldi $17, -5($31) ldi $18, 0($31) ale0%=: ldi $17, 1($17) ldi $18, 1($18) ble $17, ale0%=
导致汇编器不过.
查了一会发现有一个方法是使用临时标签.
其定义方式为N:
(N为任意数).
这是汇编器的特性而不是编译器的特性, 所以兼容性会好很多.
比如:asm volatile("ldi %0, -5($31)\n\t" "ldi %1, 0($31)\n\t" "1:\n\t" "ldi %0, 1(%0)\n\t" "ldi %1, 1(%1)\n\t" "ble %0, 1b\n\t" "bgt %0, 1f\n\t" "1:\n\t" : "=r"(a), "=r"(b));
其中
1:
就是临时标签, 跳转到临时标签需要额外声明是向前跳转还是向后跳转, 比如ble %0, 1b\n\t
中的1b
是跳转到前一个1:
, 相对的1f
就是跳转到后一个1:
生成的.s文件中为:ldi $17, -5($31) ldi $18, 0($31) 1: ldi $17, 1($17) ldi $18, 1($18) ble $17, 1b bgt $17, 1f 1:
可见这种写法并没有在编译器层面被处理, 而通过汇编器然后反汇编得到的结果是:
10: fb ff 3f fa ldi a1,-5 14: 00 00 5f fa ldi a2,0 18: 01 00 31 fa ldi a1,1(a1) 1c: 01 00 52 fa ldi a2,1(a2) 20: fd ff 3f ce ble a1,18 <.LCFI_main_store26+0x8> 24: 00 00 20 d2 bgt a1,28 <.BB2_main>
可以看出在使用临时标签的.s文件在经过汇编器处理后会丢弃其中的临时标签, 这样可以避免标签名冲突.