在最近的Windows二进制文件中(例如,win 8.1 x64)和使用VC ++'call'指令编译的程序仍然存在。将返回地址存储到寄存器中的方式不是更快更好的方法,与大多数参数相同,而不是仍然使用堆栈吗?
我的意思是:
功能:
func:
; do something
jmp r8
实例:
lea r8, [rip + tmp_1 - tmp_0] ; or rip + 'jmp func' size
tmp_0:
jmp func
tmp_1:
; rest of code
答案 0 :(得分:12)
现代x86微架构有多种通过堆栈进行呼叫的方式几乎是免费的:
1.专用堆栈引擎,在OoO执行期间使堆栈指针与堆栈操作保持同步
2.硬件返回堆栈,用于保存返回地址以便快速访问。
此外,整个架构与MIPS不同。 MIPS和大多数其他RISC都是加载存储的,这意味着它们必须将返回地址存储在寄存器中,否则call/return
必须加载/存储操作,弄乱正交性指令集的结构。
x86是一种寄存器存储器架构,针对这些访问进行了优化,特别是对于微操作融合等现代微架构特性,弥补了相对较少的寄存器数量。 。
最后,这只会加速专门在寄存器上运行的叶子函数。这种工作量大多可以内联,将函数调用成本降低到零
底线:不值得。