裸机 RISC-V CPU - 处理器如何知道从哪个地址开始获取指令?

2024-01-20

我正在设计自己的 RISC-V CPU,并且已经能够实现一些指令代码。

我已经安装了 RV32I 版本的 GCC 编译器,所以我现在有了汇编器riscv32-unknown-elf-as可用的。

我正在尝试仅用一条指令来汇编一个程序:

# simple.asm
add x5,x6,x7

我使用汇编器编译它,然后使用以下命令运行 objdump:

riscv32-unknown-elf-as simple.asm -o simple
riscv32-unknown-elf-objdump -D simple

这会打印出以下内容:

new:     file format elf32-littleriscv


Disassembly of section .text:

00000000 <.text>:
   0:   007302b3                add     t0,t1,t2

Disassembly of section .riscv.attributes:

00000000 <.riscv.attributes>:
   0:   2d41                    jal     0x690
   2:   0000                    unimp
   4:   7200                    flw     fs0,32(a2)
   6:   7369                    lui     t1,0xffffa
   8:   01007663                bgeu    zero,a6,0x14
   c:   00000023                sb      zero,0(zero) # 0x0
  10:   7205                    lui     tp,0xfffe1
  12:   3376                    fld     ft6,376(sp)
  14:   6932                    flw     fs2,12(sp)
  16:   7032                    flw     ft0,44(sp)
  18:   5f30                    lw      a2,120(a4)
  1a:   326d                    jal     0xfffff9c4
  1c:   3070                    fld     fa2,224(s0)
  1e:   615f 7032 5f30          0x5f307032615f
  24:   3266                    fld     ft4,120(sp)
  26:   3070                    fld     fa2,224(s0)
  28:   645f 7032 0030          0x307032645f

我的问题是:

  1. 这里发生了什么?我以为我会有一个简单的单行十六进制,但还有很多事情要做。
  2. 如何指示我的处理器开始读取某个内存地址处的指令?看起来 objdump 也不知道指令从哪里开始。

需要明确的是,我目前将我的处理器视为裸机。我想象我将在处理器中进行硬编码,指令从内存地址 X 开始,数据在内存地址 Y 可用,堆栈在内存地址 Z 可用。这是正确的吗?或者这是错误的方法?


@PeterCordes 的回答让我走上了正确的道路。我终于弄清楚如何生成可以使用的原始内存转储文件。

步骤如下:

  1. 修改了程序集文件以具有.text and .data部分和一个_start标签。我的simple.asm文件现在如下所示:

    .globl _start
    
    .text
    _start:
      add x5,x6,x7
    
    .data
    L1: .word 27
    
  2. 组装.asm to a .o使用以下命令创建文件:

    riscv32-unknown-elf-as simple.asm -o simple.o
    
  3. 为特定处理器创建链接描述文件。我关注了这个惊人的video https://www.youtube.com/watch?v=B7oKdUvRhQQ它演示了从头开始创建链接器脚本的过程。现在,我只需要.text and .data部分。所以我的链接器脚本(mycpu.ld)如下图所示:

    OUTPUT_FORMAT("elf32-littleriscv", "elf32-littleriscv", "elf32-littleriscv")
    ENTRY(_start)
    
    MEMORY
    {
      DATA (rwx) : ORIGIN = 0x0, LENGTH = 0x80
      INST (rx) : ORIGIN = 0x80, LENGTH = 0x80
    }
    
    SECTIONS
    {
      .data :
      {
        *(.data)
      }> DATA
    
      .text :
      {
        *(.text)
      }> INST
    }
    
    
  4. 使用生成ELF文件riscv32-unknown-elf-gcc它会自动调用riscv32-unknown-elf-ld:

    riscv32-unknown-elf-gcc -nostdlib -T mycpu.ld -o simple.elf simple.o
    
  5. 从以下位置创建原始二进制或十六进制文件.elf我将使用它来填充内存内容的文件。

    riscv32-unknown-elf-objcopy -O binary simple.elf simple.hex
    

Final simple.hex包含以下内容(使用hexyl):

┌────────┬─────────────────────────┬─────────────────────────┬────────┬────────┐
│00000000│ 1b 00 00 00 00 00 00 00 ┊ 00 00 00 00 00 00 00 00 │•0000000┊00000000│
│00000010│ 00 00 00 00 00 00 00 00 ┊ 00 00 00 00 00 00 00 00 │00000000┊00000000│
│00000020│ 00 00 00 00 00 00 00 00 ┊ 00 00 00 00 00 00 00 00 │00000000┊00000000│
│00000030│ 00 00 00 00 00 00 00 00 ┊ 00 00 00 00 00 00 00 00 │00000000┊00000000│
│00000040│ 00 00 00 00 00 00 00 00 ┊ 00 00 00 00 00 00 00 00 │00000000┊00000000│
│00000050│ 00 00 00 00 00 00 00 00 ┊ 00 00 00 00 00 00 00 00 │00000000┊00000000│
│00000060│ 00 00 00 00 00 00 00 00 ┊ 00 00 00 00 00 00 00 00 │00000000┊00000000│
│00000070│ 00 00 00 00 00 00 00 00 ┊ 00 00 00 00 00 00 00 00 │00000000┊00000000│
│00000080│ b3 02 73 00             ┊                         │וs0    ┊        │
└────────┴─────────────────────────┴─────────────────────────┴────────┴────────┘

where b3027300是十六进制值add x5,x6,x7.

就是这样!非常感谢@PeterCordes 的帮助! :)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

裸机 RISC-V CPU - 处理器如何知道从哪个地址开始获取指令? 的相关文章

随机推荐

  • Linux 上的 C++ 开发 Code::Blocks、EMACS 或 GVIM [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 如何在多个项目之间共享声明式管道

    我在不同的存储库中有很多项目 它们共享相同的基本 CI 工作流程 我可以轻松地将其表达为声明式管道 pipeline agent any options buildDiscarder logRotator numToKeepStr 20 s
  • 使用相同关键字并条件 Django 查询

    我有一个带有发布模型和标签模型的 Django 应用程序 每份出版物都有一个或多个与其关联的标签 我想使用一组两个标签查询数据库 并且仅返回同时具有这两个标签的出版物 尽管我确信它很容易获得 但我似乎找不到它的语法 我想我没有使用正确的语言
  • 为什么我的应用程序没有绘制任何东西?

    我对 C 一般编程 非常陌生 阅读了 3 周的经验 从 html css 和 javascript 开始 现在开始使用 C 我正在尝试以 Windows 形式制作自己的简单 绘画 应用程序 但我遇到了一个问题 只是无法解决它 无论我阅读或遵
  • 如何在 Javascript 中替换字符串中的撇号?

    给定一个 Javascript 中的字符串 例如 var str this s kelly 我想用另一个字符替换撇号 这是我到目前为止所尝试过的 str replace quot A str replace A 这些都不起作用 我该怎么做
  • 追踪有用信息

    这里聪明的程序员如何跟踪他们在多年的经验中获得的方便的编程技巧和有用的信息 诸如有用的编译器参数 IDE 快捷方式 巧妙的代码片段等 当我查找一两年前我曾经知道的东西时 我有时会感到沮丧 我最喜欢的 IE 可能代表了 20 世纪 90 年代
  • Linq 多个 OR 与列表

    我目前正在开发一个使用 LINQ 的 C 项目 我想知道是否可以使用 Linq 创建一个 多个 OR 子句 并将列表作为 where 的条目 我的意思是这样的 var listofId var sqlQuery from T in myta
  • 加载共享库时出错:?:无法打开共享对象文件:没有这样的文件或目录

    我正在尝试诊断 并修复 位于多个组件边界上的问题 非常感谢任何有关如何获取更多信息或彻底解决问题的见解 我有一个应用程序 它作为 C 程序启动 可以启动 Java 程序 然后可以以递归方式启动相同的 C 程序 它已经在 Linux 和 Cy
  • 了解 WebSocket

    我的理解是 一个socket对应一个网络标识符 端口和TCP标识符 1 操作系统使进程能够与端口关联 IIUC 是使进程在网络上可针对入站数据进行寻址的一种方式 因此 WebSocket 服务器通常会与众所周知的用于接受和理解升级请求的 H
  • Javascript 将字符串匹配到部分匹配

    如何在 Javascript 中进行部分字符串匹配 例如匹配 阿尔夫 阿尔弗雷德 gt 正确 阿尔夫 gt 正确 alf gt 真 al gt 真 改变 gt false 一半 gt 假 gt 假 鲍勃 gt 假 https jsfiddl
  • 将单索引数据帧添加到多索引数据帧、Pandas、Python

    如何将单个数据框添加到多索引数据框 例如 我的多索引数据是 Name Code Buying Date Buying Price Buying Qty Date Code 20140117 none a 1234 20170101 5 7
  • 连接两个 Pandas 数据框

    请给出两个数据框 DF1 A B a1 b1 a2 b2 a3 b3 DF2 C1 C2 C3 0 0 1 我想做以下 DF1 DF2 产生以下结果 A B C1 C2 C3 a1 b1 0 0 1 a2 b2 0 0 1 a3 b3 0
  • 打开Refine - 将另一个文件添加到现有项目中

    我已将 CSV 文件导入到 OR Open Refine 由于我的 CSV 文件包含超过 200 000 条记录 我决定创建单独的文件 因为上传大文件在我的计算机中无法工作 需要很长时间 甚至不确定它是否真正导入 我能够从单个文件 大 中创
  • 相当于 JavaFX8 的 JGraph?

    我想将一个使用旧版本 JGraph 的旧 swing 工具移植到 JavaFX8 然而 由于 JGraph 是一个基于 Swing 的库 因此也考虑替换它 那么 是否有类似于 JGraph 的东西 但与 JavaFX8 一起使用 那么 是否
  • 将类添加到特定类名上的 .hover 功能 - jQuery

    因此 在我的整个文档中 我希望每次用户将鼠标悬停在具有特定类名称的元素上时 我都希望添加一个类 我的 CSS 看起来像这样 hotspot hover hotspothover border 4px solid fff box shadow
  • 查找并重命名所有文件扩展名不正确的图片

    我正在寻找一种方法来自动重命名所有文件扩展名错误的图像 到目前为止 我至少找到了如何获取所有这些文件的列表 find media folder name jpg exec file grep PNG GIF gt foobar txt fi
  • 在scala中玩框架表单验证

    scala 中 play 框架表单验证的工作 跟随我的 Signup 对象 它在 mapping missing 对象表单中方法映射的参数 遵循此方法与 如果你想 将其视为部分应用函数 case class UserRegistration
  • getAllCellInfo 在 android 4.2.1 中返回 null

    我的 Android 版本是 4 2 1 我正在尝试使用TelephonyManager getAllCellInfo 方法 在我的清单文件中我有ACCESS COARSE UPDATES ACCESS COARSE LOCATION AC
  • Jquery Ajax 中的函数作为参数

    是否可以将函数放入 Jquery Ajax 的参数中 如下所示 dataType 和 data 作为函数给出 如果返回类型为 JSON 则 dataType 返回 JSON 值 如果 isJson 为 false 则返回文本 dataVal
  • 裸机 RISC-V CPU - 处理器如何知道从哪个地址开始获取指令?

    我正在设计自己的 RISC V CPU 并且已经能够实现一些指令代码 我已经安装了 RV32I 版本的 GCC 编译器 所以我现在有了汇编器riscv32 unknown elf as可用的 我正在尝试仅用一条指令来汇编一个程序 simpl