零/符号扩展是无操作的,为什么要为每种大小类型提供指令呢?

2024-03-21

对于 x86 和 x64 编译器生成类似的零/符号扩展 MOVSX 和 MOVZX。扩展本身并不是免费的,但允许处理器执行无序魔法加速。

但在 RISC-V 上:

因此,无符号和有符号 32 位整数之间的转换是无操作,从有符号 32 位整数到有符号 64 位整数的转换也是如此。

加法和移位需要一些新指令(ADD[I]W/SUBW/SxxW),以确保 32 位值的合理性能。

(C) RISC-V 规范

但与此同时,新型现代 RISC-V 64 位处理器包含 32 位有符号整数指令。为什么?为了提高性能?那么8位和16位在哪里呢?我已经什么都不懂了。


完整的引用对我来说似乎很清楚:

编译器和调用约定维护一个不变式,即所有 32 位值都保存在 64 位寄存器中的符号扩展格式。即使是 32 位无符号整数也会将第 31 位扩展为第 63 位 到 32。

因此,无符号和有符号 32 位整数之间的转换是无操作的, 从有符号 32 位整数到有符号 64 位整数的转换也是如此。
现有64位宽 SLTU 和无符号分支比较仍然可以在无符号 32 位整数上正确运行 这个不变量。
类似地,现有的 32 位符号扩展整数上的 64 位宽逻辑运算 保留符号扩展属性。

一些新指令(ADD[I]W/SUBW/SxxW)是 加法和移位所需的,以确保 32 位值的合理性能。

它表示 32 位值存储在 64 位寄存器中,其 MSb(最高有效位)通过位 32-63 重复。
这是为了both签署并unsigned整数。

这允许进行一些优化,如引用中所述:

  • 无符号有符号转换是免费的。
    将此与通常的算法进行比较,在通常的算法中,您必须将低 32 位值置零或进行符号扩展,以将其提升为具有不同“符号性”的 64 位值(忽略溢出)。
  • 有符号 32 位 有符号 64 位是免费的。
    这节省了符号扩展。
  • 分支和设置指令仍然有效。
    这是因为重复 MSb 不会改变比较结果。
  • 逻辑 64 位运算保留此属性
    经过几个例子就很容易看出这一点。

然而,加法(举个例子)并不能保留这个不变式: 0x000000007fffffff + 0x0000000000000001 = 0x0000000080000000 这违反了假设。

由于 a) 使用 32 位值的情况经常发生,并且 b) 修复结果需要额外的工作(我可以考虑使用slli/srai对)引入了新的指令格式。
这些指令在 64 位寄存器上运行,但仅使用其较低的 32 位值,并对 32 位结果进行符号扩展。
这很容易在硬件中完成,因此值得拥有这种新的指令。

正如评论中所指出的,8 位和 16 位算术很少见,因此没有花费任何工程精力来为其寻找新的空间(无论是在所需的门还是所使用的操作码空间方面)。

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

零/符号扩展是无操作的,为什么要为每种大小类型提供指令呢? 的相关文章

  • 内联汇编 - cdecl 和准备堆栈

    我最近一直在尝试通过使用缓冲区和不同汇编运算符的原始十六进制等效项来实现 C 中的动态函数 为了说明一个简单的跳转 byte buffer new buffer 5 buffer 0xE9 Hex for jump uint buffer
  • x86 实模式下的段大小

    我对实模式下段的大小有一个疑问 因为它们不能超过 64K 但可以小于那个 http support microsoft com kb 120069 我的问题是这些段大小和基地址是如何初始化的 就像保护模式下有 GDT 和 LDT 一样 实模
  • 如何查看JVM中JIT编译的代码?

    有什么方法可以查看 JVM 中 JIT 生成的本机代码吗 一般用法 正如其他答案所解释的 您可以使用以下 JVM 选项运行 XX UnlockDiagnosticVMOptions XX PrintAssembly 根据特定方法进行过滤 您
  • 英特尔® 事务同步扩展新指令 (TSX-NI) 与英特尔 TSX 有何不同?

    我在Intel的页面上找到了 https ark intel com products 97123 Intel Core i5 7500 Processor 6M Cache up to 3 80 GHz https ark intel c
  • elf .rel.text 部分中 R_386_32/R_386_PC32 的含义

    为了理解重定位的概念 我编写了一个简单的 chk c 程序 如下所示 1 include
  • 推送 64 位 intel osx

    我想将 64 位地址压入堆栈 如下所示 asm pushq 0x1122334455667788 但我得到编译错误 我只能按以下方式推送 asm pushq 0x11223344 有人可以帮助我理解我的错误吗 我是装配新手 所以如果我的问题
  • 汇编中如何计算负数

    我是汇编新手 我有一个关于如何表示负数的问题 我有三个 DWORDS 变量 比方说 result DWORD 0 i DWORD 3 j DWORD 5 我想计算这个公式 结果 i j 8 但是 当我执行 i j 时 由于符号 结果将是一个
  • 一条指令可以同时处于两种寻址模式吗?

    我在书中读到了以下内容从头开始编程 处理器有多种不同的访问数据的方式 称为 寻址模式 最简单的模式是立即模式 其中 要访问的数据嵌入在指令本身中 例如 如果我们想将寄存器初始化为 0 而不是给出 计算机要从中读取 0 的地址 我们将指定立即
  • Clang 使用 -nostdlib 生成崩溃代码

    我正在尝试为可执行文件设置自己的运行时环境 但无法使用 clang v3 4 1ubuntu1 目标 x86 64 pc linux gnu 来生成没有段错误的可执行文件 我已将问题简化为以下内容 如果我有一个文件 crt1 c 除了满足
  • 如何让c代码执行hex机器代码?

    我想要一个简单的 C 方法能够在 Linux 64 位机器上运行十六进制字节码 这是我的 C 程序 char code x48 x31 xc0 include
  • 在 x86 程序集中将整数打印到控制台

    当我在 16 位汇编中添加两个值时 将结果打印到控制台的最佳方法是什么 目前我有这个代码 CODE START mov ax 1 put 1 into ax add ax 2 add 2 to ax current value mov ah
  • 为什么 Solaris 汇编器生成的机器代码与 GNU 汇编器在这里不同?

    我为 amd64 编写了这个小汇编文件 对于这个问题来说 代码的作用并不重要 globl fib fib mov edi ecx xor eax eax jrcxz 1f lea 1 rax ebx 0 add rbx rax xchg r
  • 汇编基础知识:输出寄存器值

    我刚刚开始学习汇编语言 我已经陷入了 在屏幕上显示存储在寄存器中的十进制值 的部分 我使用 emu8086 任何帮助将不胜感激 model small Specifies the memory model used for program
  • 在 x86-64 CPU 上通过交叉修改代码重现意外行为

    Question 对于可能在 x86 或 x86 x64 系统上触发意外行为的交叉修改代码有哪些想法 在这些系统中 交叉修改代码中的所有操作均已正确完成 但在执行处理器之前执行序列化指令除外修改代码 如下所述 我有一个 Core 2 Duo
  • 为什么当大小大于 50 时,该程序花费的时间会呈指数级增长?

    所以我正在为类编写一个 ARM 汇编快速排序方法 我对大部分内容都有了解 除了复杂性没有意义 我们将其与我们制作的另一种冒泡排序方法进行比较 它对于具有 1 个参数和 10 个参数的示例表现更好 然而 我什至无法比较 100 个参数测试 因
  • 有没有办法使用 i387 fsqrt 指令获得正确的舍入?

    有没有办法使用 i387 fsqrt 指令获得正确的舍入 除了改变精确模式在 x87 控制字中 我知道这是可能的 但这不是一个合理的解决方案 因为它存在令人讨厌的重入型问题 如果 sqrt 操作中断 精度模式将出错 我正在处理的问题如下 x
  • “rep stos”x86 汇编指令序列有什么作用?

    我最近偶然发现了以下汇编指令序列 rep stos dword ptr edi For ecx重复 存储内容eax到哪里edi指向 递增或递减edi 取决于方向标志 每次 4 个字节 通常 这用于memset型操作 通常 该指令简单地写成r
  • 大会,你好世界问题

    我正在 Linux 上学习 asm noobuntu 10 04 我得到了以下代码 http asm sourceforge net intro hello html http asm sourceforge net intro hello
  • 弹出 x86 堆栈以访问函数 arg 时出现分段错误

    我正在尝试链接 x86 程序集和 C 我的C程序 extern int plus 10 int include
  • 从 exe 文件中获取汇编级代码?

    我当时正在做linux汇编编程 在过去的几天里我已经转而学习windows汇编编程 我在用ml作为我的汇编器和golink作为我的链接器 我有我的汇编代码并已获得我的exe从中 现在我需要取回它的十六进制 xff xab x55等等 在li

随机推荐

  • 三张牌排成一行,而不是所有牌排成一列

    我正在使用 React 和 Material UI 我在一个数组中有 40 张动态卡 当我渲染它们时 我想要连续 3 张卡 并将所有卡放在一列中 我正在使用这张卡 https codesandbox io s r084q99q34 http
  • 我可以在 OS X 中进行 Java 6 开发吗?

    我知道当 Leopard 推出时 每个人 嗯 每个 Java 开发人员并且足够关心在 Mac 上进行开发 都对没有 Java 6 SDK 支持感到愤怒 我知道有人在 Leopard 发布几个月后提供了某种破解方法 但我可以发誓 我稍后读到
  • 从我的数据框中创建虚拟变量矩阵;使用“NA”来查找缺失值

    我有一个基于不同年份的数据 重复了几次 我希望我的输出具有等于年数的列 每列代表一年 现在 目的是分别为每年创建虚拟变量 例如 只要主数据中存在与 2000 年平行的非 NA 观测值 2000 年的输出列就必须具有值 1 否则为 0 而且
  • 从 Firebase 通知恢复应用程序不起作用(Xamarin Forms)

    我正在努力整合Firebase 推送通知到我的应用程序 请找到我的火力基地Firebase消息服务 class 如果应用程序打开并运行 则一切正常 但是 如果应用程序未打开 如果我切换到其他应用程序 我的应用程序未关闭 我收到通知 但当我点
  • 帮助在 Rails 中构建模型

    class Profile has many projects through gt teamss has many teams foreign key gt member id has many own projects class na
  • Jenkins:动态作业创建引发“管道 CPS 方法不匹配”错误

    我正在尝试从应并行运行的管道作业之一创建多个动态作业 我希望我的詹金斯管道脚本根据用户输入下载并安装我的软件二进制文件 以下是我的示例阶段 第 1 阶段 将下载构建版本 第 2 阶段 获取参数并安装软件的 云 部分 第 3 阶段 将接受用户
  • Mongoose populate() 返回空数组

    所以我已经花了大约4个小时 阅读了几次文档 但仍然无法找出我的问题 我正在尝试对我的模型执行一个简单的 populate 我有一个用户模型和商店模型 用户有一个 favoriteStores 数组 其中包含商店的 id 我正在寻找的是这个数
  • SQL查询where参数为null不为null

    我正在尝试执行 SQL 查询并根据参数是否为空或否动态构建 where 条件 我有这样的事情 SELECT tblOrder ProdOrder tblOrder Customer FROM tblOrder CASE WHEN Order
  • 找不到模块“内部/错误”离子

    我正在尝试创建新的离子项目 然后它显示以下错误 我已经删除了nodejs npm ionic并再次重新安装 但再次出现相同的错误 Terminal https i stack imgur com vLP7J png Error Error
  • 使用 Ajax 加载用户控件

    我试图找到使用 Ajax 加载用户控件的最佳实践 我的第一种方法是简单地使用 UpdatePanel 并在 ajax 回发上使用 LoadControl 弹出它 但这会在同一 UpdatePanel 中重新呈现其他加载的用户控件 另外 我无
  • cassandra 节点限制

    我正在寻找 cassandra 是否有节点硬件规格的限制 例如如果存在任何此类限制 每个节点的最大存储可能是多少 我打算使用几个节点 每个节点具有 48TB 存储 2TB X 24 硬盘驱动器 7200rpm 并配有一些良好的双 Xeon
  • SMTP 验证错误“发送邮件失败”

    如果满足某些条件 我将尝试从我的 ASP NET 网页发送电子邮件 这是我的代码 SmtpClient smtpClient new SmtpClient NetworkCredential basicCredential new Netw
  • 如何找到 Homebrew 的可安装软件包列表?

    最近我安装了Brew https brew sh 如何检索要安装的可用brew 软件包的列表 brew help将显示可用命令的列表 brew list将显示已安装软件包的列表 您还可以附加公式 例如brew list postgres会告
  • 当请求为 POST 时,在 Apigee HTTPTargetConnection 上调用 GET

    我需要调用使用 GET 的旧版 API 我的 API 代理使用 POST 我尝试使用AssignMessage
  • 将一个字符串更改为另一个字符串的简单突变数量?

    我相信你们都听说过 文字游戏 在这种游戏中 您试图通过一次更改一个字母来将一个单词更改为另一个单词 并且只浏览有效的英语单词 我正在尝试实现一个 A 算法来解决它 只是为了充实我对 A 的理解 并且需要的东西之一是最小距离启发式 也就是说
  • Angular 单元测试 Jasmine Spy 错误

    以下控制器收到类型错误 未定义 不是函数 正在评估sessionService getCurrentPlace 我有一个模拟服务 该方法正在被监视 模拟服务上的另一种方法工作正常 我试过了 AndReturns 关于间谍以及 AndCall
  • 在 MATLAB 中为结构体数组的字段赋值

    我想替换结构体数组中字段的值 例如 我想在以下结构中将所有 1 替换为 3 a 1 b 1 a 2 b 2 a 3 b 1 a a b 1 b 3 This doesn t work and spits out Insufficient o
  • 是否有一个“空”printf 代码不打印任何内容,用于跳过参数?

    如果我想要一个程序有多种文本输出格式 我可以这样做 const char fmtDefault u x s 2f each n const char fmtMultiLine Qty 3u nItem s nPrice per item 2
  • Kartik Select2 - 以编程方式更改多个

    我有一个 yii2 activeform 其中表单的功能可以根据表单中的其他内容进行更改 所以 我有一个俱乐部字段 在某些情况下可以是多个 但在其他情况下不能是多个
  • 零/符号扩展是无操作的,为什么要为每种大小类型提供指令呢?

    对于 x86 和 x64 编译器生成类似的零 符号扩展 MOVSX 和 MOVZX 扩展本身并不是免费的 但允许处理器执行无序魔法加速 但在 RISC V 上 因此 无符号和有符号 32 位整数之间的转换是无操作 从有符号 32 位整数到有