为什么 RISC-V S-B 和 U-J 指令类型以这种方式编码?

2024-05-06

我正在读一本书《计算机组织与设计RISC-V版》,我遇到了 S-B 和 U-J 指令类型的编码。

我上面提到的那些类型有奇怪的编码立即字段。

S-B 类型将直接字段分为两部分。这是有道理的,因为所有指令编码都必须相似。但我无法理解为什么立即字段以下面这种方式编码。

imm[12, 10:5], imm[4:1, 11]

代替

imm[11:5], imm[4:0]

U-J 类型也有这个奇怪的编码立即字段

imm[20,10:1,11,19:12]

代替

imm[19:0]

谁能解释一下吗?


所选择的编码与其他编码非常吻合,简化了硬件,但牺牲了必须生成指令的软件、必须解码指令的软件以及学习或使用 RISC V 的程序员;)。

S 格式将立即数分解为imm[11:5] and imm[4:0]。这个立即数被分解的原因是保留其他字段,即寄存器字段,rs2 and rs1,与 R 类型指令中两个源寄存器字段的位置相同。 (与 MIPS 相比,MIPS 的做法类似但不完全,这消除了寄存器名称宽度(例如 5 位宽)多路复用器和一些额外的接线以及控制信号。)

S 格式允许 12 位立即数。

而分支的 (S)B 类型使用 13 位立即数,尽管 13 位立即数的最后一个(最低有效位)始终为零所以它没有被存储!因此,它实际上需要像 S-Format 一样编码 12 位,但由于它们在实际使用中会移位(左移 1,例如 *2),因此与 S-Format 相比,所有位本质上都偏移了 1 位位置。立即格式化。 (移位并不困难或缓慢,但会耗费硅空间。通常,这种恒定量的移位可以通过简单地将输入位连接到偏移输出位位置来完成,而不是使用我们在 ALU 中看到的专用移位器;然而,这仍然是直接的数据路径大小的布线,因此〜12到32+额外的电线。)

为了不必(尽可能多地)移动直接的部分that is存储,并且为了与 S 格式的立即数很好地对齐,未存储的 LSB 位置(来自 S 格式)用于存储 SB 格式立即数的位 11。这样位 10:1 排列起来exactly与 S 格式立即。

但为什么不直接将分支的第 12 位放在那里,这样可以多保留一位与 S 格式对齐(即 11:1)?因为指令立即数中编码的最高位用于将立即数符号扩展为 32 位(对于 RV32,或者对于 RV64,为 64 位;对于 RV128,为 128 位,需要很多电线!)。因此,通过将符号位保持在与 S 格式 12 位立即数相同的位置,可以共享相同的符号扩展硬件(具有与上面首先描述的相同的优点和缺点;-)。因此,选择将 SB 类型立即数的下一个最高有效位 11 位存储在 0 位位置(相对于 S 格式)。

SB(已经给定 S)的成本仅为两根左右(1 位)电线、一个 1 位多路复用器和一个 1 位控制信号 — 与替代方案相比,成本最低。

请参阅以下内容推介会 http://inst.eecs.berkeley.edu/~cs61c/resources/su18_lec/Lecture7.pdf,幻灯片 46,标题为“RISC-V 立即编码”,副标题为:“为什么这么混乱?!?!”

UJ-Type 的做法类似,将符号位保持在与其他指令的符号位相同的位位置,同时将尽可能多的其他位与其他格式对齐。

请参阅同一演示文稿的幻灯片 60。

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

为什么 RISC-V S-B 和 U-J 指令类型以这种方式编码? 的相关文章

  • 将 2 个数字与汇编进行比较[关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 我有以下代码 我想完成汇编代码 如下
  • GCC 内联 asm NOP 循环在编译时未展开

    走出我通常的 VC 领域 进入 GCC 的世界 通过 MINGW32 尝试创建一个主要由 NOP 组成的 Windows PE ala for i 0 i lt 1000 i asm nop 但要么我使用了错误的语法 要么编译器正在通过它们
  • 如何检测字符串字节编码?

    我读取了大约 1000 个文件名os listdir 有些是UTF8编码 有些是CP1252 我想将它们全部解码为 Unicode 以便在我的脚本中进一步处理 有没有办法让源编码正确解码为 Unicode Example for item
  • 如何使用 LOCK ASM 前缀来读取值?

    我知道如何使用 LOCK 来线程安全地递增一个值 lock inc J 但是如何以线程安全的方式读取 J 或任何值 LOCK 前缀不能与 mov 一起使用 如果我执行以下操作 xor eax eax lock add eax J mov J
  • 为什么 NASM 在使用有效的指令助记符作为操作数中的符号名称方面没有问题?

    我编写了以下简单程序 但 nasm 拒绝编译它 section text global start start mov rax 0x01 mov rdi 0x01 mov rsi str mov rdx 0x03 syscall mov r
  • 当下一条(跳过)指令是变量定义时,Shellcode 中的 JMP 意外行为

    Purpose 我试图利用 x86 64 中的 RIP 模式 尽管程序集本身按预期执行 但 shellcode 却没有 问题 简而言之 我尝试过的是这样的 jmp l1 str1 db some string l1 other code l
  • jQuery:将 json 响应的编码设置为 utf8

    我收到了 json 格式的 jQuery 响应 逻辑工作正常 但我无法让他正确编码数据 如 我搜索并发现this https stackoverflow com questions 26620 how to set encoding in
  • 0 和双字 0 有什么区别?

    正如问题所述 有什么区别 例如 mov eax 0 and mov eax dword 0 我一直在使用 cmp 语句 但我无法理解其中的区别 一个是地址 另一个是数值 如前所述 MOV 指令没有区别 对于 CMP 您将有以下区别 qwor
  • C++ 字符串:UTF-8 还是 16 位编码?

    我仍在尝试决定我的 家庭 项目是否应该使用UTF 8 http en wikipedia org wiki UTF 8字符串 根据 std string 实现 必要时带有附加的 UTF 8 特定函数 或一些 16 位字符串 作为 std w
  • 为什么我可以访问寄存器中较低的双字/字/字节,但不能访问较高的双字/字/字节?

    我开始学习汇编程序 这对我来说看起来不合逻辑 为什么我不能在寄存器中使用多个高字节 我明白了历史原因rax gt eax gt ax 所以让我们关注new64 位寄存器 例如 我可以使用r8 and r8d 但为什么不呢r8dl and r
  • X86 汇编将小写字母转换为大写字母

    实现toUpper函数 将字符串中的小写字母转换 为大写 该函数采用一个参数 char string 字符串是一个 char类型指针 指向字符串的开头 因为C 样式字符串以零结尾 我们不需要取长度 字符串作为另一个参数 我需要帮助开始 我不
  • RISC-V反汇编器与秒杀运行结果不符?

    我已经设置了一个 hello world 程序只是为了测试我的riscv32 unknown elf工具链 spike pk等等虽然我设法使用打印了 hello worldspike isa RV32 pk hello elf 我发现如果我
  • 调用/返回/jmp等后x86代码执行?

    我希望这个问题不会太愚蠢 因为它看起来似乎很明显 当我对缓冲区溢出进行一些研究时 我偶然发现了一个简单的问题 调用 返回 跳转后转到新指令地址后 CPU是否会执行该地址处的OP代码 然后将一个字节移动到下一个地址并执行下一个OP代码 依此类
  • 使用 XCHG 解锁的自旋锁

    维基百科提供的使用 x86 XCHG 命令的自旋锁的示例实现是 Intel syntax locked The lock variable 1 locked 0 unlocked dd 0 spin lock mov eax 1 Set t
  • 更改使用文本文件的 SSIS 日志提供程序创建的文件的文件编码

    我是 SSIS 新手 我已经设计了一个包并为文本文件配置了 SSIS 日志提供程序 这工作正常并且日志文件已成功生成 我们有一个监控团队 他们使用这个日志文件进行监控 他们无法读取日志文件 因为文件编码是 Unicode 格式 他们期望使用
  • 替换非 UTF8 字符

    在 php 中 我需要替换字符串中的所有非 UTF8 字符 然而 并不是通过某种等价物 比如iconv功能与 TRANSLIT 但是由一些选定的角色 例如 or 例如 通常 我希望用户能够看到找到无效字符的位置 我没有找到任何执行此操作的函
  • 如何将 nvarchar 解码为文本(SQL Server 2008 R2)?

    我有一个 SQL Server 2008 R2 表nvarchar 4000 field 存储该表的数据如下所示 696D616765206D61726B65643A5472 or 303131 011 我看到每个字符都编码为十六进制 我如
  • 为什么 x86-64 上的 GCC 在函数内插入 NOP?

    给定以下 C 函数 void go char data char name 64 strcpy name data x86 64 上的 GCC 5 和 6 编译 普通gcc c g o其次是objdump 这到 00000000000000
  • 尝试理解 printf() 的 gcc 汇编输出

    我正在尝试学习如何理解汇编代码 因此我一直在研究 GCC 的汇编输出以获取一些愚蠢的程序 其中之一只不过是int i 0 我现在或多或少完全理解了其中的代码 最大的困难是理解散布的 GAS 指令 无论如何 我向前迈了一步并添加了printf
  • 内存映射图形输出

    我正在探索使用内存映射图形绘制像素和线条 我在 Windows 的 Textpad 中使用 TASM 当我单击 运行 时 整个屏幕变成蓝色 就是这样 没有绘制像素 model small stack data saveMode db xVa

随机推荐