繁体   English   中英

(GNU内联汇编)如何使用既没有分配也没有复制到C变量的寄存器?

[英](GNU inline assembly) How to use a register which not assigned from nor copy to the C variables?

我正在使用基于GNU的工具链编写内联汇编语句,并且内联汇编中包含三条指令来更新系统寄存器的单个位。 步骤将是:

  1. 将系统寄存器移动(读取)到通用寄存器
  2. 将其与C代码中的变量值“与”
  3. 移动(写入)回到系统寄存器,只需读取

在我使用的指令集中,内联汇编语法如下:

unsigned int OV_TMP = 0xffefffff;
asm volatile ( "mfsr %0, $PSW\n\t"
               "and %0, %0, %1\n\t"
               "mtsr %0, $PSW"
               :  : "r"(OV_TMP) : );

%1是我要将OV_TMP的值转发到的寄存器。

%0对我来说是问题,我的问题是: 一旦内部使用了一个寄存器,并且未从C代码的C变量中分配或复制到该变量,如何编写内联汇编代码?

从编译器的角度来看,这里要考虑的事情是,即使您以后不再使用它,寄存器由内联程序集分配给它。 也就是说,您生成的等效项是:

register unsigned int OV_TMP = 0xffefffff, scratch;

scratch = magic() & OV_TMP;
more_magic(scratch);
/* and then don't re-use scratch for anything from here on */

由于volatile ,魔术步骤和/或more_magic步骤无法移动或合并,因此编译器不能简单地删除已写入但未使用的寄存器。

在我看来, mfsrmtsr就像是powerpc指令,我可能会在C代码中执行and步骤(请参见脚注); 但以下方法通常应该起作用:

unsigned int OV_TMP = 0xffefffff, scratch;
asm volatile("mfsr %0, $PSW\n\t"
             "and %0, %0, %1\n\t"
             "mtsr %0, $PSW"
             : "=&r"(scratch) : "r"(OV_TMP));

此处的“ =&r”约束条件是在读取输入操作数( %1 )之前先写入输出操作数( %0 )。


脚注:据我所知(不是很远,我只做过一点点ppc组装),无需将mfsrmtsr指令保持特定的距离,这与其他上的某些锁定步骤序列不同处理器。 如果是这样,我会写更多这样的东西:

 static inline unsigned int read_psw() { unsigned int result; asm volatile("mfsr %0, $PSW" : "=r"(result)); return result; } static inline void write_psw(unsigned int value) { asm volatile("mtsr %0, $PSW" :: "r"(value)); } #define PSW_FE0 0x00100000 /* this looks like it's FE0 anyway */ ... write_psw(read_psw() & ~PSW_FE0); /* some appropriate comment here */ 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM