我的代码是

unsigned long user_stack_pointer;

__asm__(
    ".global exception_handling_entry\n"
    "exception_handling_entry:\n"
    "add %0, sp, x0\n"
    : "=r" (user_stack_pointer)
);

gcc在使用riscv64-unknown-elf-gcc test.c -o test时显示错误')' before ':' token.但是当我把内联asm放到一个函数中时,

unsigned long user_stack_pointer;

int main() {
    __asm__(
    ".global exception_handling_entry\n"
    "exception_handling_entry:\n"
    "addi %0, sp, 0\n"
    : "=r" (user_stack_pointer)
    );

    return 0;
}

这让我很困惑.

我找不到解决这个问题的好办法.

推荐答案

在全局范围内,代码只有在ASM语句本身内部发生跳转时才会运行.C语言中的执行路径无法进入和离开asm语句,因此编译器没有地方放置设置输入操作数或将输出操作数存储到相关C变量的代码.如果您希望发生这种情况,请使用you have to write code for it yourself, exactly like writing a function in a separate 101 file.(在全局作用域ASM语句中使用.text,以防编译器留下当前部分的其他内容.)

例如sd sp, user_stack_pointer作为伪指令,或者auipc具有地址的%hi部分并使用%lo(user_stack_pointer)作为存储指令中的偏移量.看看编译器生成的ASM,看看它是如何访问全局vars(https://godbolt.org/)的;我只是从内存出发,这可能不太适合RV64;我可能还记得MIPS.

或者,如果您想让编译器为您执行.global和标签,请使用__attribute__((naked)).您仍然需要用基本的asm语句(没有操作数)编写整个函数体;it's not officially supported to use Extended 103 (with operands) in naked functions:https://gcc.gnu.org/onlinedocs/gcc/RISC-V-Function-Attributes.html--但它最多只是一个警告,而不是编译时错误,所以编译器不会阻止您依赖碰巧工作代码.

此外,编译器不会在naked函数的末尾发出ret,因此无论如何都不能让执行出现在ASM语句的底部,从而使输出操作数变得毫无用处.你得跑到ret英里或者跳到某个地方.


如果执行跳到中间之后从ASM语句的底部出来(例如,像这个异常处理程序,而不是从C __asm__语句本身开始执行),无论它在哪里,甚至在函数内部,实际上都是未定义的行为.作为the GCC manual documentsasm statements may not perform jumps into other asm statements, only to the listed GotoLabels. GCC’s optimizers do not know about other jumps; therefore they cannot take account of them when deciding how to optimize.

如果这真的奏效,那你就走运了."=r"(global_var)操作数的代码可能依赖于一些寄存器,这些寄存器是由编译器放在asm语句前面的指令设置的,如果您跳到asm语句的中间,这些指令就不会执行.

C++相关问答推荐

函数指针始终为零,但在解除引用和调用时有效

自定义malloc实现上奇怪的操作系统依赖行为

球体—立方体重叠:无、部分或全部?

标准的C17标准是用括号将参数包装在函数声明中吗

在编译时参数化类型定义

C lang:当我try 将3个或更多元素写入数组时,出现总线错误

在每种If-Else情况下执行语句的最佳方式

如何使用_newindex数组我总是得到错误的参数

将字符串数组传递给C中的函数:`str[dim1][str_size]`vs`*str[dim1]`

预处理器宏扩展(ISO/IEC 9899:1999(E)§;6.10.3.5示例3)

C语言中MPI发送接收字符串时出现的分段错误

Printf()在C中打印终止字符之后的字符,我该如何解决这个问题?

如何在不使用字符串的情况下在c中编写函数atof().h>;

Fprintf正在写入多个 struct 成员,并且数据过剩

为什么WcrTomb只支持ASCII?

为什么会导致分段故障?(C语言中的一个程序,统计文件中某个单词的出现次数)

即使我在C++中空闲,也肯定会丢失内存

在我的第一个C语言中观察到的错误';你好世界';程序

If语句默认为true

Clang 是否为内联汇编生成了错误的代码?