Tra*_*rap 5 x86 assembly coding-style
我正在x86汇编程序中编写一些程序来修改ZF作为返回布尔值的方法,所以我可以这样做:
call is_value_correct
jz not_correct
Run Code Online (Sandbox Code Playgroud)
我想知道这是否被认为是不好的做法,因为一些编码标准说应该在AX寄存器中返回简单的值.
是的,如果它使您的代码运行更快和/或整体更小,那就去做吧.
手动编写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
Run Code Online (Sandbox Code Playgroud)
如果你愿意为了风格或可读性而牺牲效率,你可能不应该在2018年首次编写asm,因为编译器大多数时候都能生成好的asm,你很少需要编写自己的启动部门或其他什么.(即性能是手写asm的主要用例,只有你全力以赴才能获得性能.)
是的,手写的asm可能成为一个难以理解/不可维护的混乱,但如果它具有合理的语义含义,那么这种优化不会使你的代码变得混乱.
甚至有这样的先例:x86-64 OS X系统调用使用CF作为错误/无错误状态,与rax
返回值分开.与Linux不同的是,RAX从-4095到-1指示错误,但是它们使用相同的x86-64 System V ABI /调用约定.
一些DOS int 0x21
系统调用和PC BIOS int 0x10
功能具有类似的标志返回系统.它允许调用程序分支出错,因此它可以节省代码大小(测试或cmp)并避免需要带内错误信号.