【发布时间】:2021-10-17 14:35:21
【问题描述】:
当前使用此 64 位 MASM 代码调用 C 运行时函数,例如 memcmp()。我记得这个约定来自GoAsm article 优化。
memcmp PROTO;:QWORD,:QWORD,:QWORD
PUSH RSP
PUSH QWORD PTR [RSP]
AND SPL,0F0h
MOV R8,R11
MOV RDX,R10
MOV RCX,RAX
SUB RSP,32
CALL memcmp
LEA RSP,[RSP+40]
POP RSP
这是一个有效的优化版本吗?
memcmp PROTO;:QWORD,:QWORD,:QWORD
PUSH RSP
PUSH QWORD PTR [RSP]
AND RSP,-16 ; new
MOV R8,R11
MOV RDX,R10
MOV RCX,RAX
LEA RSP,[RSP-32] ; new
CALL memcmp
LEA RSP,[RSP+40]
POP RSP
更换的理由
AND SPL,0F0h
与
AND RSP,-16
是它避免调用部分寄存器更新。 Understanding fastcall stack frame
更换
SUB RSP,32
与
LEA RSP,[RSP-32]
接下来的指令不依赖于减法更新的标志
那么不更新标志也会更有效。
Why does GCC emit "lea" instead of "sub" for subtraction?
在这种情况下,还有其他优化技巧吗?
【问题讨论】:
-
AND是的,原始代码很愚蠢,没有节省任何代码大小(SPL 采用 REX 前缀)。LEA- 毫无意义且浪费代码大小:x86 CPU 已经通过寄存器重命名避免了对 FLAGS 的错误依赖。该链接问答的答案是错误的。 -
@PeterCordes 旁注: 感谢您看到这个。我打算在您的一个回复下链接评论以提醒您注意这一点,但决定稍等一下,因为我认为您会根据您的正常 M/O 找到它。
标签: c assembly x86-64 micro-optimization