- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我最近做了很多 x64 汇编编程(在 Linux 上)
用于与我的 C/C++ 程序集成。
因为我最关心的是效率,所以我喜欢尽可能少地使用不同的 regs/内存地址,并且尽量不创建任何堆栈帧或保留寄存器(每个周期计数)。
根据 cdecl r10 和 r11 寄存器未保留,我希望将它们用作函数中的临时变量,最好不保留。
它是否会导致任何编译器的不可比性问题/错误(到目前为止还没有遇到任何问题,但这是一个问题)?
最佳答案
x86-64 System V ABI 不会将其调用约定称为“cdecl”。这只是 x86-64 SysV 调用约定。字符串“cdecl”没有出现在 the ABI doc 中.r11
是一个临时的,又名调用破坏的寄存器。r10
也是一个被调用破坏的寄存器。 ABI 说“用于传递函数的静态链指针”,但 C 不使用它,gcc 和 clang 生成的代码可以自由使用 r10
不保存/恢复它。 ABI 的寄存器使用列表表 r10
未跨函数调用保留 所以叶函数总是可以破坏它。 ( Which registers to use as temporaries when writing AMD64 SysV assembly? )
gcc 确实使用 r10
作为其 trampoline for function pointers to GNU C nested functions 的一部分, 用于指向外部作用域的堆栈帧的指针。栈上机器码的蹦床是hack,但这确实是一个静态链指针;适当支持嵌套函数的语言可能会让调用者意识到它(如 lambda/闭包)并在 r10
中传递一个值。使用指向嵌套函数的指针时。
非叶函数不需要传递它们的传入 r10
给他们的 child ,除非他们是支持那种东西的语言(不是 C 或 C++)中的“嵌套函数”。 因此 r10
也是纯临时在正常情况下。r10
和 r11
不是传递参数的寄存器,与其他调用破坏的寄存器不同,因此“包装器”函数可以使用它们(尤其是 r11
)而无需保存/恢复任何内容。
在正常功能中,RBX、RBP 和 RSP 与 R12..R15 一起是调用保留的。所有其他人都可以在不保存/恢复的情况下被破坏。 (这包括 xmm/ymm0..15 和 zmm0..31、x87 堆栈以及 RFLAGS 中的条件代码)。
请注意 r8..15
需要一个 REX 前缀,即使是 32 位操作数大小(如 xor r10d, r10d
)。如果您有一些 64 位非指针整数,请确保将它们保存在 r8..r11 中,因为无论何时使用这些值,您总是需要一个 REX 前缀来表示 64 位操作数大小。
较小的代码大小通常不会更糟,有时有助于解码和 uop 缓存密度,以及 L1i 缓存密度。 RAX、RCX、RDX、RSI、RDI 应该是您临时注册的首选。 (除非您需要 64 位,否则请使用 32 位操作数大小。例如 xor eax,eax
是将 RAX 归零的正确方法。Silvermont 不将 xor r10,r10
识别为归零习语,因此使用 xor r10d,r10d
即使它没有'不节省代码大小。)
如果您确实用完了低寄存器,最好使用 r10
/r11
对于通常会与 64 位操作数大小(或 VEX 前缀)一起使用的东西。例如指向 64 位数据的指针或指向指针的指针。 mov eax, [r10]
需要一个 REX 前缀,而 mov eax, [rdi]
没有。但是mov rax, [rdi]
和 mov r8, [r10]
大小相同。
很难获得太多 yield ,因为您经常需要在不同的组合中同时使用不同的值,例如最终使用 cmp eax, r10d
或者其他什么,但如果你想全力以赴优化,那么考虑代码大小。也许还要考虑指令边界在哪里以及它将如何适应 uop 缓存。
见 x86 tag wiki ,尤其是 http://agner.org/optimize/有关编写高效代码的提示。
关于assembly - 常规使用 r10 和 r11 的可接受性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49928950/
当给定两个 bool 参数时,^ 运算符执行异或,例如 true ^ true == false true ^ false == true false ^ true == true false ^ f
我需要下载一个文件(例如: https://www.betaseries.com/srt/391160 )所以我在网上找到了不同的方法: def download(String remoteUrl,
可以说,我们正在计算考试成绩的平均值: 起始考试成绩:75、80、92、64、83、99、79 平均值= 572/7 = 81.714 ... 现在给出81.714,如果您不知道初始测试分数,是否可以
我和一个 friend 正在争论线程池中的线程数应该是处理器计数+ 1还是仅仅是处理器计数。 我之所以选择处理器数量,是因为每个处理器可以分配偶数个线程,而他选择处理器数量+ 1是因为他认为这将帮助他
我已经养成了尽可能使用闭包来代替常规方法的习惯,即使我不需要访问自由变量。所以,我将使用这个: def addNumbers = { 左、右 -> 左 + 右 } ..而不是这个: def addNu
我对 Groovy 非常陌生,我正在尝试《Groovy in Action》书中的这个示例。我有这个 fibonacci.groovy 程序,当尝试使用 java 命令运行该程序时,我收到 NoCla
我有 3 个 TextView 。我需要将它们的权重设置为 Light、Regular 和 Condensed。有人可以帮助我了解如何在 Android 中实现这一点吗? 最佳答案 在 TextVie
如果用户启动我的应用程序并最初选择不允许位置服务,我想通过 UIAlertMessage 提示用户重新考虑(“更新”和“不,谢谢。”)。 “不,谢谢。”这将是一个简单的取消,我希望“更新”将它们直接链
如何在 groovy 中显示一个值是真还是假?我使用 Eclipse 作为我的 IDE。 assert 4 * ( 2 + 3 ) - 6 == 14 //integers only 而且我也
我的问题与“多处理器编程的艺术”一书有关。第4章介绍安全/常规/原子寄存器及其实现。 以下是安全多读取器单写 boolean 寄存器的以下实现,该寄存器基于安全单读取器单写 boolean 寄存器,被
使用下面的代码来保存 float 的值 domainInstance.standardScore = params["standardScore"] as float 在这种情况下,我的输入是 17.
使用下面的代码来保存 float 的值 domainInstance.standardScore = params["standardScore"] as float 在这种情况下,我的输入是 17.
在iOS的about部分中,它具有有关设备的大量信息。 我和我可以访问此信息吗? 我想快速获取settings -> General -> About的数据。在iOS中获得相同的价格是否可行? 最佳答
我正在开发Windows服务,它将承载两件事: WCF服务 用于定期作业执行的“常规” Windows服务(使用Quartz.net) 因此,基本上,一个应用程序(可执行)承载这两种服务类型。 这两种
在mysql中,我有一个名为users的表,其中包含系统中的用户列表... id | name | surname | active ____________________________ 1
所以我在 Debian 服务器上设置了一个 MySQL 数据库,并且它在 phpMyAdmin 客户端上运行良好。我目前正在开发一个项目,编写一个 Java 服务器,该服务器能够通过 JDBC 连接使
已关闭。这个问题是 not reproducible or was caused by typos 。目前不接受答案。 这个问题是由拼写错误或无法再重现的问题引起的。虽然类似的问题可能是 on-top
前两天考试了,其中一道题是把@前面的字母换成新的名字 所以在试卷中我们有 array = "toto@yahoo.com","mimi@yahoo.com".soso@yahoo.com"所以我们应该
大家好 如果字符串语法如下,我如何从字符串中获取数字(正数): t_def_type_id_2 t_def_type_id_22 t_def_type_id_334 所以,在第一个字符串中我想得到 1
我正在寻找不会在内核中阻塞的文件描述符类型。我知道我可以使用 fstat(2) 但 fstat 还会给我各种元数据信息(访问时间等),这些信息可能会阻塞任意时间(特别是在网络文件系统上)。 编辑:我正
我是一名优秀的程序员,十分优秀!