gpt4 book ai didi

assembly - 将标志寄存器用作 bool 返回值是否被认为是不好的做法?

转载 作者:行者123 更新时间:2023-12-04 14:09:01 25 4
gpt4 key购买 nike

我在 x86 汇编器中编写了一些程序来修改 ZF 作为返回 bool 值的一种方式,所以我可以这样做:

call is_value_correct
jz not_correct

我想知道这是否被认为是不好的做法,因为一些编码标准说应该在 AX 寄存器中返回简单的值。

最佳答案

如果它使您的代码运行得更快和/或整体更小,请执行此操作。
这不是坏习惯。

手工编写 asm 的优点之一是能够使用自定义调用约定函数,即使它们不是私有(private)帮助函数或宏。这包括能够“返回”不同寄存器中的多个值,并且基本上可以做任何你想做的事情。
与任何自定义调用约定一样,您需要做的就是用注释记录它。这是一个示例,说明您如何使用一组特定且有意非标准的事物来编写此类评论。

# inputs:   foo in EAX (zero-extended into RAX), bar in EDI
# pre-requisites: DF=0
# clobbers: RCX, RDX, AL (but not the rest of EAX)
# returns: AL = something, ZF = something else
my_func:
...
setc al
...
something that sets ZF
ret
如果您愿意为了样式或可读性而牺牲效率,那么您可能不应该在 2018 年首先使用 asm 编写,因为编译器大部分时间都能够生成良好的 asm,而且您很少需要编写自己的 Bootstrap 部门或其他。 (即性能是手写 asm 的主要用例,只有在你全力以赴的情况下才合适。)
是的,手写 asm 可能会变得难以阅读/无法维护,但如果在具有合理语义含义的情况下仔细处理,这种优化不会让您的代码变得一团糟。

这样做甚至有先例: x86-64 OS X system calls use CF as the error/no-error status , 与 rax 分开返回值。与 Linux 不同,错误由从 -4095 到 -1 的 RAX 返回值指示,尽管它们使用相同的 x86-64 System V ABI/调用约定。
一些 DOS int 0x21系统调用和 PC BIOS int 0x10函数具有类似的标志返回系统。它允许调用者在错误时分支,因此它节省了代码大小(测试或 cmp)并避免需要带内错误信号。

内联汇编
顺便说一句,在内联汇编中,不是编写整个函数,您可以而且应该在 FLAGS 中输出一些东西,而不是浪费指令在寄存器中实现 bool 值,特别是如果编译器只是去 test再说一遍。 Condition-code output constraints从 GCC6 开始支持,参见 this answer例如。
但安全不易 call asm 内部的函数如果要使用 C 调用具有自定义调用约定的函数,则声明。您需要告诉编译器每个调用破坏的寄存器都被破坏了。包括 st0..7、mm0..7、x/y/zmm0..31 和 k0..7(如果支持 AVX-512,否则编译器甚至不知道这些 reg 名称)。或者只有你的手写 asm 函数实际上破坏了那些,如果你想致力于保持与函数的实际实现同步的约束。
call本身会插入踩到红色区域。见 Calling printf in extended inline ASM举一个应该安全的例子。

关于assembly - 将标志寄存器用作 bool 返回值是否被认为是不好的做法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48381234/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com