几天前我已经开始使用risc-v,但昨天我遇到了问题.问题如下:
我想为RV32I基本整数指令集编译代码,我想添加"M"标准扩展.
当我编译C代码时,我使用以下命令
riscv64-unknown-elf-gcc Program.c -o Program.o -m32 -march=RV32IM
Run Code Online (Sandbox Code Playgroud)
现在,如果我想看到汇编程序代码,我使用
riscv64-unknown-elf-objdump -d Program.c > Program.dump
Run Code Online (Sandbox Code Playgroud)
现在,如果我探索转储文件"Program.dump".我注意到有时会出现汇编指令:
10c6c: 00a12427 fsw fa0,8(sp)
10dd0: 00a42023 sd a0,8(sp)
Run Code Online (Sandbox Code Playgroud)
在许多其他情况下.
如果我在第52页看到"RISC-V指令集手册,第I卷:用户级ISA,版本2.0",我发现fsw指令属于RV32F标准扩展和sd指令,它属于RV64I.
出于这个原因,我很困惑,我不知道我的问题是我的编译不好.
我的问题是:如何仅为RV32I基本整数指令和扩展M编译C代码?
我已经下载了最新的...
RISC-V指令集手册,第1卷:用户级ISA
...这很有趣,但是它实际上从未提供操作码/ funct3和其他指令格式的值。例如,按名称列出了LOAD / STORE / BRANCH操作码,但没有提供它们代表的实际位值。
实际列出的所有代码在哪里?
默认情况下,用于Risc-V的GCC会nop在生成指令后生成指令call:
$ cat test.c
void g();
void f() {
g();
}
$ riscv64-unknown-elf-gcc -S test.c -o -
[...]
f:
addi sp,sp,-16
sd ra,8(sp)
sd s0,0(sp)
addi s0,sp,16
call g
nop #### <-----------here
ld ra,8(sp)
ld s0,0(sp)
addi sp,sp,16
jr ra
.size f, .-f
.ident "GCC: (GNU) 8.3.0"
Run Code Online (Sandbox Code Playgroud)
我希望当针对具有分支延迟时隙的架构时,但是我的理解是Risc-V不是这样的架构。实际上,nop使用-O1或更高版本进行编译时消失。
只是GCC中的“错误”会nop从具有延迟插槽的体系结构中遗留下来,还是有此nop指令的实际原因?
简介:
我买了一块配备GD32VF103 Risc-V MCU的Longan Nano评估板。
我可以运行视频播放器演示,并使用 VS Code、PlatformIO 和 DFU 工具编译和加载工作代码。下面是电路板和演示运行的视频。

https://www.youtube.com/watch?v=84_PzcNiJb4
我想做的
就是为机器人比赛建造一个机器人作为一种爱好。我使用 Microchip 4809 8 位 MCU 作为电机控制器,但在以 2KHz 运行 PID 控制器时达到了 MCU 的极限,而且我还没有添加电流环路。我想升级电机控制器,我决定选择 Longan Nano,因为它有 LCD 屏幕、优越的 CPU 马力以及学习 Risc-V。
https://www.youtube.com/watch?v=1dQMktoiuLg
问题
我可以在轮询中很好地运行 Longan Nano 的外围设备。我真的很努力地想让中断起作用,但没有成功。我尝试读取轮询中断标志,它们就是这样工作的,所以我认为这要么是 ISR 处理程序链接到 Start.s 中的中断向量表的链接器问题,要么是 ECLIC 的配置问题。
这是一个正确运行的轮询示例。红色 LED 以 2Hz 的频率闪烁,按下启动按钮将切换蓝色 LED。
#include <gd32vf103.h>
void init()
{
rcu_periph_clock_enable(RCU_GPIOA);
rcu_periph_clock_enable(RCU_GPIOC);
gpio_init(GPIOA, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_1);
gpio_init(GPIOA, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_2);
gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ,GPIO_PIN_8);
gpio_init(GPIOC, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_13);
gpio_bit_set(GPIOC,GPIO_PIN_13);
gpio_bit_set(GPIOA,GPIO_PIN_1);
gpio_bit_set(GPIOA,GPIO_PIN_2);
rcu_periph_clock_enable(RCU_AF);
eclic_init(ECLIC_NUM_INTERRUPTS);
eclic_priority_group_set(ECLIC_PRIGROUP_LEVEL3_PRIO1);
eclic_irq_enable(EXTI5_9_IRQn, 1, 1);
exti_deinit(); …Run Code Online (Sandbox Code Playgroud) 让我们尝试定义一个返回两个值 x 和 y 中的最大值的函数。这些公式有效的充分条件是,对于有符号整数,\xe2\x80\x932^30 <= x, y <= 2^30 \xe2\x80\x93 1,对于无符号整数,0 <= x, y <= 2^31 \xe2\x80\x93 1(即,只需要处理有效减少一位的缩小整数范围)。最通用(且最简单)的实现是:
int max(int x, int y) {\n return (x > y) ? x : y\n}\nRun Code Online (Sandbox Code Playgroud)\n在 Pentium Pro 之前,这将是 x86 中生成的程序集:
\nmax: # GCC -O3 -march=pentium -m32\n mov eax, DWORD PTR [esp+8]\n cmp eax, DWORD PTR [esp+4]\n jge .L4\n mov eax, DWORD PTR [esp+4]\n.L4:\n ret\nRun Code Online (Sandbox Code Playgroud)\n但从 Pentium Pro 开始,CMOVcc r32,r/m引入了一条新指令,它根据某些指定的状态标志执行条件移动: …
我正在尝试为基于 RISC-V 的板创建一个引导程序。我正在遵循本指南,并将其调整为 riscv。 osdev
我遇到的问题是翻译这条指令。
times 510 -( $ - $$ ) db 0
我能想到的最好的方法是只填充 63 行,.8byte 0
但这似乎不太可行。
这是完整的代码。
#################################
########### Boot Init ###########
#################################
.section .text
start: # begins the program
nop # the do nothing instruction
j start # loops back to start
# Todo:: figure out the size of the np and j instruction
# The intent of this portion is to fill the remaning bin file with 0's up until the last two …Run Code Online (Sandbox Code Playgroud) 加载和存储指令对编码有相同的要求:两个寄存器和一个 12 位立即数。然而,存储指令(sb、sh、sw)具有称为S 型的专用格式,而加载指令使用与 addi 指令相同的I 型格式。
我不明白为什么加载和存储不共享指令格式,但存储只有自己专用的指令格式(S-type)。
我正在学习 RISC-V 汇编,我需要将数组用于我正在解决的练习;问题是我正在使用的模拟器(RARS)给了我一个错误:
Error in /home/username/file_name line 8: Runtime exception at 0x00400010: address out of range 0x000003e8.
这是我到目前为止编写的代码:
.data
arr: .word 1000
e0: .word 5
.text
lw t1, arr # load arr into t1
lw t2, e0 # Load e0 value into t2
sw t2, 0(t1) # save t2 value into arr[0]
Run Code Online (Sandbox Code Playgroud)
我在做什么错?
RISC-V 调用约定规定寄存器 a0 和 a1 可用于返回值,而不是所有 8 个寄存器 a0~a7。当需要“返回”两个以上的值时,我们可以使用堆栈。为什么?这样做有什么好处吗?
我正在学习 RISC-V 语言,作为计算机体系结构研究的一部分。我注意到我们可以使用所有八个 a0~a7 寄存器将参数传递给函数,但根据一些 RISC-V 调用约定,只有其中两个(a0 和 a1)可用于返回返回值,例如了解 RISC-V 调用约定和RISC-V 调用约定。我很困惑为什么约定包含只有 a0 和 a1 应该用于返回的规则。我浏览了上面提到的两篇文章,但没有找到任何解释这一点的内容。在我看来,这些a0~a7寄存器在函数调用之间不被保留,这表明我们可以在函数中自由地使用它们。因此,如果需要,我们可以而且应该使用它们中的任何一个来传递返回值,以方便和高效。总之,有什么理由要求我们限制返回值到a0和a1寄存器吗?
PS我刚刚注意到这个问题Whytworeturnregisters(inmanyprocedurecallsconventions/ABIs),它告诉我连续的寄存器可以用于大数字。然而,我的观点是,为什么我们限制自己在a2~a7中放入更多的返回值,即使看起来没有明显的缺点?或者,如果我使用a2~a7作为返回值,违反约定,会不会很糟糕?
我们正在做一个项目,其中arm64处理器是主处理器,加速器设备内部有RISC-V。并且可以从ARM64处理器访问RISC-V处理器的CSR寄存器(地址映射)。顺便说一句,我们的设计人员出于我们的目的定义并添加了一些 CSR 寄存器。
RISC-V处理器中是否有CSR寄存器显示当前PC值?或者只能从 RISC-V 内核内部使用auipc x1, 0设置 RISC-V 寄存器之类的指令来读取 PC?我发现一些CSR寄存器是为异常PC或陷阱向量定义的,但在CSR寄存器列表中找不到当前的真实PC值。
我想读取RISC-V内核的PC值,看看RISC-V指令是否正在处理。但是,如果 PC 值未反映在这些 CSR 寄存器之一中,我将无法从 arm64 处理器读取 PC 值。我的理解正确吗?