关于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文件在经过汇编器处理后会丢弃其中的临时标签, 这样可以避免标签名冲突.


登录后回复