我正在阅读这本书Programming from the Ground Up by Jonathan Barlett,用于在Linux上学习i386程序集
我的目的是阅读一些用asm编写的项目源代码,然后我遇到了这个LODSL
,从手册中我可以知道它从%esi
指向的地方加载数据,然后增加地址大小
那么为什么人们不能只使用movl
来做到这一点?是因为我没有考虑任何速度提升或任何其他问题吗?
答案 0 :(得分:5)
为什么人们不能只使用movl来做到这一点?
代码大小,ADD修改标志。 (虽然你可以通过使用LEA来指示增量来避免这种情况。)
存在大多数复杂的单字节指令的主要原因之一是8086在代码获取方面几乎完全成为瓶颈。除了内存通常是宝贵的事实,代码大小〜=第一代x86 CPU的代码速度。现代CPU绝对不是这种情况,具有快速指令缓存和耗电量大的解码器,甚至caches for decoded instructions。
交换寄存器与AX的单字节指令是现代x86的8个宝贵操作码的巨大浪费,但显然对8086有用,因为MOVSX直到386才存在(所以你需要CBW) ,和其他东西需要AX。 (并且XCHG的吞吐量不比现在的MOV差3倍)。有趣的事实:0x90 NOP来自xchg eax, eax
的编码。
是任何速度改进
是的,代码大小始终很重要。
此外,在英特尔P6系列和Sandybridge系列中,LODSD(在语法中称为lodsl
)直到Haswell为3 uop。在Haswell上,LODSD / Q仅为2 uops。 (LODSB / W仍为3 uops)。请参阅Agner Fog's instruction tables and microarch pdf标记wiki中的x86和其他链接,例如英特尔优化手册。
因此,直到Haswell,它可能最好使用单独的MOV和ADD指令,除非代码大小非常重要(例如在引导加载程序中,速度几乎无关紧要)。