简体   繁体   English

如何在ASM内联语句中请求通用寄存器?

[英]How to ask for a general purpose register in an asm inline statement?

Is there a way to ask gcc to allocate a register for asm inline internal use only? 有没有一种方法可以要求gcc分配一个仅用于asm内联内部使用的寄存器? Here is an example (in pseudo-asm) where r5 is directly used in the asm, but it could be any general purpose register, it is only for internal use, so neither an input nor an output : 这是一个示例(在伪asm中),其中r5直接在asm中使用,但是它可以是任何通用寄存器,仅用于内部使用,因此既不是输入也不是输出:

asm("load_immediate_value %%r5,0;"
    /* ... */
    "add_immediate_value %%r5,%%r5,42"
    /* ... */
    :
    :
    : "r5");

In this example, I choose register r5 and tell gcc that I am using it through the clobber list. 在此示例中,我选择寄存器r5,并通过Clobber列表告知gcc我正在使用它。 But what if r5 is an ABI register?! 但是,如果r5是ABI寄存器怎么办? I need a way to simply ask for a register without having to name it myself. 我需要一种方法来简单地请求注册,而无需自己命名。

The way this is usually done is: 通常这样做的方式是:

static __inline__ void set_archctrl0(unsigned long val) {
    register unsigned long archctrl0 __asm__("archctrl0") = val;

    __asm__ __volatile__("" : "+r"(archctrl0) : : "cc", "memory");
}

The empty asm statement is there only to force the compiler not to optimize the whole thing out. 空的 asm语句仅用于迫使编译器优化整个过程。

Or, a more practical example, reading the stackpointer register can be done like: 或者,举一个更实际的例子,读取堆栈指针寄存器可以像这样完成:

static __inline__ void * getSP(void) {
    register void * sp asm("sp");
    asm ("" : "=r"(sp));
    return sp;
}

The method to bind variables to specific registers is documented in the Explicit Register Variables section of the GCC manual. 变量绑定到特定寄存器的方法在GCC手册的“ 显式寄存器变量”部分中进行了介绍。

Of course, if writing the arch-specific register requires a custom instruction (ie cannot be done using whatever type of "move" or "load" the CPU normally uses to initialize register values), you'll rather require something like: 当然,如果编写特定于拱的寄存器需要一条自定义指令(即无法使用CPU通常用于初始化寄存器值的任何类型的“移动”或“装载”来完成),则您需要以下内容:

static __inline__ void set_archctrl0(unsigned long val) {
    __asm__ __volatile__("setarchctrl0 %0" : : "r"(val) : "cc", "memory");
}

All of those, obviously, only work for registers that are not being used by "normal" code (ie outside the platform ABI / explicitly reserved by the platform ABI as globals / as regs not to be touched by compiled code). 显然,所有这些仅适用于未被 “正常”代码使用的寄存器(即,在平台ABI外部/平台ABI明确保留为全局变量/编译代码不会触及的regs)。

You cannot instruct the compiler to "keep its hands off a general-purpose register" this way. 您不能通过这种方式指示编译器“将其手从通用寄存器中移开”。 To my knowledge, that isn't possible in gcc. 据我所知,这在gcc中是不可能的。

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

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