如何强制gcc在asm中使用两个不同的寄存器来操作数?

pep*_*er0 3 assembly gcc

我正在使用为sam7s处理器编译的gcc 4.6.3.

我需要使用一些内联汇编:

int res;
asm volatile (" \
        MRS r0,CPSR     \n  \
        MOV %0, r0      \n  \
        BIC r0,r0,%1    \n  \
        MSR CPSR,r0     \n  \
        " : "=r" (res) : "r" (0xc0) : "r0" );
return res;
Run Code Online (Sandbox Code Playgroud)

由gcc翻译为(由我添加的评论):

mov r3, #192    ; load 0xc0 to r3
str r0, [sl, #56]   ; preserve value of r0?

mrs r0, CPSR    ; load CPSR to r0
mov r3, r0      ; save r0 to "res"; r3 overwritten!
bic r0, r0, r3  ; 
msr CPSR_fc, r0 ; 
Run Code Online (Sandbox Code Playgroud)

问题是代替"%0"(res)和"%1"(常数:0xc0),使用相同的寄存器"r3".因此,%1在使用之前会被覆盖,并且代码工作不正确.

问题是我如何禁止gcc使用相同的寄存器作为输入/输出操作数?

pep*_*er0 5

好的,最后我在这里找到了它

&表示在
读取输入之前写入输出操作数,因此该输出不能与任何输入相同.
如果没有这个,即使"0"约束不需要,gcc也可以将输出和输入放在同一个寄存器中.这非常有用,但这里提到的是因为它特定于替代方案.与=和%不同,但是像?,你必须将它包含在它适用的每个替代方案中.

改变后"=r" (res),以"=&r" (res)一切工作正常.