简体   繁体   English

C:返回通用寄存器

[英]C: Return general purpose register

I have the following function which makes a supervisor call.我有以下功能可以拨打主管电话。

inline uint32_t os_SVC(uint32_t n, uint32_t pid, void* ptr1, void (*ptr2)()){
  __asm("svc #0");
  return;
}

By altering the stack during the SVC ISR I know R0 will contain the return argument from the SVC ISR.通过在 SVC ISR 期间更改堆栈,我知道 R0 将包含来自 SVC ISR 的返回参数。 As I understand it, this is how the AAPCS returns values from functions.据我了解,这就是 AAPCS 从函数返回值的方式。 But how do I return the R0 register from os_SVC ?但是如何从os_SVC返回 R0 寄存器? Currently it gives me a warning because I am returning from the function without supplying a return value.目前它给了我一个警告,因为我从函数返回而不提供返回值。

Your compiler may have further extensions that allow you to pass data in and out of the assembly insert.您的编译器可能有进一步的扩展,允许您将数据传入和传出程序集插入。 You didn't tell us which compiler you're using, so I'm going to show you how to do it with GCC, which is the one whose extensions I remember without looking it up:您没有告诉我们您使用的是哪个编译器,所以我将向您展示如何使用 GCC 来完成它,我记得它的扩展名没有查过它:

uint32_t os_SVC(uint32_t n, uint32_t pid, void *p1, void (*p2)(void))
{
    register uint32_t rv asm ("r0");
    asm ("svc #0" : "=r" (rv))
    return rv;
}

The register ... asm ("r0") annotations on the declaration of rv require the compiler to put it in r0, and the : "=r" (rv) annotation on the asm statement tells it that the assembly instruction writes to that variable. rv声明上的register ... asm ("r0")注释要求编译器将其放入 r0 中,而 asm 语句上的: "=r" (rv)注释告诉它汇编指令写入该多变的。 Then you can return rv as normal.然后你可以正常返回rv

Also, notice how I removed the inline ?另外,请注意我如何删除inline That was intentional.那是故意的。 If you inline this function, the arguments won't be neatly lined up on the stack where the system call expects to find them.如果您内联此函数,参数将不会整齐地排列在系统调用期望找到它们的堆栈上。 If your operating system expects system call arguments in registers, you could annotate the assembly insert further and make an inline work, but if it expects them on the stack, leaving the function out-of-line is the best approach.如果您的操作系统需要寄存器中的系统调用参数,您可以进一步注释程序集插入并进行内联工作,但如果它需要它们在堆栈中,则将函数保持在外线是最好的方法。 (In production code I would put __attribute__((noinline)) on the function itself and __attribute__((used)) on each of its arguments, but that would be too much clutter for an example.) (在生产代码中,我会将__attribute__((noinline))放在函数本身上,并将__attribute__((used))放在它的每个参数上,但这对于示例来说太混乱了。)

The documentation for the extensions I'm using are in the "Using Assembly Language with C" section of the GCC manual.我正在使用的扩展的文档在 GCC 手册的“使用 C 语言使用汇编语言”部分。 Read the entire thing very carefully.非常仔细地阅读整篇文章

If you are not using GCC, consult your compiler's manual to see if it has equivalent extensions.如果您不使用 GCC,请查阅您的编译器手册以查看它是否具有等效的扩展。 If it doesn't have equivalent extensions, your only option may be to write this function entirely in assembly language, in a separate .S file.如果它没有等效的扩展名,您唯一的选择可能是完全用汇编语言在单独的.S文件中编写此函数。

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

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