我正在x86汇编程序中编写一些程序来修改ZF作为返回布尔值的方法,所以我可以这样做:
call is_value_correct
jz not_correct
我想知道这是否被认为是不好的做法,因为一些编码标准说应该在AX寄存器中返回简单的值。
答案 0 :(得分:8)
是的,如果它使您的代码运行得更快和/或整体更小,请执行此操作。
手动编写asm的一个优点是能够使用自定义调用约定函数,即使它们不是私有帮助函数或宏。这包括能够"返回"不同寄存器中的多个值,基本上可以随心所欲。
与任何自定义调用约定一样,您需要做的就是用注释记录它。以下是您可以使用特定且有意的非标准事物撰写此类评论的示例。
# 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,而你很少需要编写自己的引导扇区或其他任何东西。 (即表演是手写asm的主要用例,只有当你全力以赴表现时才能表现出来。)
是的,手写的asm可能成为一个难以理解/无法维护的混乱,但如果它具有合理的语义含义,那么这个优化不会成功你的代码一团糟。
这样做甚至有先例:x86-64 OS X system calls use CF as the error/no-error status,与rax
返回值分开。与Linux不同,RAX指示错误从-4095到-1返回值,尽管它们使用相同的x86-64 System V ABI /调用约定。
某些DOS int 0x21
系统调用和PC BIOS int 0x10
函数具有类似的标志返回系统。它允许调用程序分支出错,因此它可以节省代码大小(测试或cmp)并避免需要带内错误信号。