这个 128 位整数乘法在汇编 (x86-64) 中如何工作?

2023-11-24

我正在阅读计算机系统:程序员的视角作业是描述这个算法是如何工作的。

C函数:

void store_prod(__int128 *dest, int64_t x, int64_t y) {
    *dest = x * (__int128)y;
}

集会:

movq %rdx, %rax
cqto
movq  %rsi, %rcx
sarq  $63,  %rcx
imulq %rax, %rcx
imulq %rsi, %rdx
addq  %rdx, %rcx
mulq  %rsi
addq  %rcx, %rdx
movq  %rax, (%rdi)
movq  %rdx, 8(%rdi)
ret

我不知道为什么它会执行:xh * yl + yh * xl = value which we add after unsigned multiplication


一如既往,编译器选项很重要。该源代码与gcc -Og(针对调试进行优化)生成与您的清单非常相似的 asm(在进行完整的 128x128 => 128 位乘法之前,强制转换将两个操作数符号扩展为 128 位)。这是 C 标准所说应该发生的事情的简单实现(用于将两个操作数转换为相同类型的整数优先规则)。

如果您要谈论编译器输出,您应该始终说明哪个版本的哪个编译器以及哪个选项。或者只是发布一个链接到godbolt,就像上面那个一样。 (编辑:哎呀,源代码和 asm 来自一本没有提供该信息的书。如果那是 CS:APP 3e 的全球版本,请注意练习题充满了错误在全球版中。)

With gcc -O3 or -O2,GCC 利用了两个操作数实际上仍然只有 64 位的事实,所以单个imul足够。 (这仍然为每个输入产生相同的结果,因此仍然按照 as-if 规则实现 C 逻辑。C 没有扩展操作,因此您被迫以“低效”方式编写源代码,这取决于编译器将其转换为高效的 asm。)


The sar $63, %rcx是符号扩展的一部分rsi into rcx:rsi, 就像cqto符号扩展rax into rdx:rax。它用原始符号位的副本替换 RCX 的每一位。


这个答案的大部分已经由其他人在评论中给出,但我认为其他人没有注意到这一点gcc -Og / -O1几乎完全给出了 asm 输出。

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

这个 128 位整数乘法在汇编 (x86-64) 中如何工作? 的相关文章

随机推荐

  • glVertexAttribPointer 内置顶点属性,如 gl_Vertex、gl_Normal

    我必须使用 glVertexAttribPointer 将顶点属性发送到期望它们作为内置的着色器 gl Vertex gl Color etc The glVertexAttribPointer函数需要指定每个内置属性的索引 或位置 我可以
  • 使用不同的 SQL 查询批量准备语句

    我发现现有的问题similar对于这个问题实际上并没有明确的答案 带有一个 sql 查询的普通批处理准备语句将如下所示 private static void batchInsertRecordsIntoTable throws SQLEx
  • 视图的 SELECT 在 FROM 子句中包含子查询

    我有两个表 我需要创建一个视图 这些表格是 credit orders id client id number of credits payment status credit usage id client id credits used
  • 带有CSS三角形的边框半径

    I have 一个矩形对角线的每一边都有自己的颜色 div width 0 height 0 border left 150px solid green border top 100px solid gray 现在我想向 div 添加边框半
  • 使我的 NumPy 数组跨进程共享

    我已经阅读了很多关于共享数组的问题 对于简单的数组来说 它似乎足够简单 但我一直试图让它适用于我拥有的数组 import numpy as np data np zeros 250 dtype float32 250000 2 float3
  • 在node.js中加载并执行外部js文件并访问局部变量?

    做一个简单的事情是否容易 可能include path to file Node js 中的命令类型 我想做的就是访问局部变量并运行脚本 人们通常如何组织比简单的 hello world 更大的 Node js 项目 功能齐全的动态网站 例
  • Excel 是否计算提供给 IF 函数的两个结果参数?

    Excel s if函数采用三个参数 一个条件 一个 if true 值和一个 if false 值 Excel 是否计算出所有三个参数的值 还是仅计算条件的值和相应的结果 澄清 我不知道是什么result of the if将会是 我想知
  • init 方法中的 [self release]、[self dealloc] 或 [super dealloc] ?

    我刚刚阅读了有关如何在 init 方法中正确失败的内容 并且文档似乎彼此不同意 一种建议抛出异常 另一种则建议清理并返回 nil 目前的最佳实践是什么 我相信普遍接受的做法是失败时返回零 但你确实想释放 self 以避免泄漏 id init
  • 如何等待数据写入管道的另一端

    我正在用 C 语言开发一个应用程序 父进程和子进程通过管道进行通信 在写入管道之前 父进程执行另一个语句 在示例代码中 我使用 sleep 10 来进行延迟 在子进程中 它应该从管道读取数据 但是子进程中管道的读取端不会读取数据 int m
  • 使用 JSoup 提取图像 src

    我正在尝试使用 jsoup 从此网页中提取所有图像网址 任何人都可以提供有关如何做到这一点的帮助吗 所有标签的格式都是这样的 但我只需要 src 图像 而不是 ajaxsrc img src http image cdnllnwnl xos
  • 使用 BACK 键隐藏键盘事件

    我注意到在Android Market Application 当您单击搜索按钮时 它会显示键盘 但是当您单击back按钮 搜索EditText变得不可见并且keyboard被隐藏 问题是我无法隐藏EditText按后退键后隐藏键盘后 因为
  • Visual Studio自定义构建步骤规则?

    使用 Visual Studio 2008 当我向 C 项目添加一个不存在的文件时 c cpp h rc或者 IDE 无法识别的任何内容都会弹出一个对话框 询问我是否要为此类文件创建自定义构建步骤规则 有谁知道如何在不添加文件的情 况下进入
  • [A]如何在javafx中使MP3重复播放?

    我希望我的 mp3 文件在完成后再次重复 但我无法创建循环来重复播放我的文件 我使用了这段代码 但只有它在完成后播放我的文件的第一秒 AudioClip myMusic myMusic setCycleCount AudioClip IND
  • 代码检查 - 命名范围参考

    在 Rubberduck 2 0 11 2453 中运行代码检查后 有 4 个范围引用被标记为 成员 Range 隐式引用 ActiveSheet 有问题的范围是指命名范围 是否有必要限定命名范围引用 Private Sub RunORat
  • gcc生成目标文件时创建目录

    gcc o abc def o def c产生def o目录中的文件abc 仅当目录存在时abc 当生成的目标文件的封闭目录不存在时 有没有办法让 gcc 创建一个目录 如果没有 那么提前自动创建目录 尤其是 Makefile 的最简单方法
  • 将 rowversion 转换为 bigint

    在我的 C 程序中 我不想使用字节数组 因此我将 rowversion 数据类型转换为 bigint SELECT CAST version AS BIGINT FROM dbo mytable 所以我收到一个数字而不是字节数组 这种转换总
  • 在 sphinx 文档中包含独立的 HTML 页面

    对于我的项目的大部分文档 我更喜欢标准的 sphinx 布局 然而 对于登陆页面 我更喜欢使用自定义 HTML CSS JS 而不使用普通 sphinx 网站的任何布局 目录或侧边栏 有没有一种方法可以在 sphinx 生成的网站中包含原始
  • 自定义属性未在样式和主题内解析

    我有一个带有自定义主题的 Android 应用程序 该应用程序是 2 3 年前开发的 我有这个风格attr xml资源文件
  • 如何在同一端口 4200 上运行 Angular 4 应用程序和 NodeJS api 以进行生产和开发?

    我已经创建了 Angular 4 应用程序 我可以使用它来运行它ng serve open它运行在localhost 4200 我想要的是我还使用创建了 apinodejs现在在同一个角度项目中我想运行该 APIlocalhost 4200
  • 这个 128 位整数乘法在汇编 (x86-64) 中如何工作?

    我正在阅读计算机系统 程序员的视角作业是描述这个算法是如何工作的 C函数 void store prod int128 dest int64 t x int64 t y dest x int128 y 集会 movq rdx rax cqt