有没有办法与处理器通信,您打算将 15 位偏移量应用于 32 位寄存器,并让它自己找出 0 填充?
否。英特尔手册中记录了可用的指令编码(其在线版本可在网上的各个地方获得;请参阅x86标签 wiki 中的链接)。对于MOV
,偏移量大小与寄存器大小相匹配。MOV
当您进入 16 位寄存器时,处理器仅使用 16 位偏移量。没有办法获得 15 位偏移量。
正如 Raymond Chen 所说,“这不像你可以随便编造 [你自己的自定义编码]”。
在某些模式下,某些指令有一个符号扩展位。
当然可以,但我不明白这对你有什么帮助。您的目标是减少指令的大小:添加一个额外的 16 位操作数大小前缀以更改对偏移大小的解释不会帮助您做到这一点。
一般来说,如果有一种更短的方法来对与原始指令等效的指令进行编码,那么汇编程序将为您发出该编码。当然NASM 会使用它的多通道优化选项(默认启用)。
这里或那里额外的 2 个字节真的会救我的命!
这不是您可以有效保存的地方之一。
正如 David Wohlferd 已经建议的那样,如果您重复执行此操作,您可以通过预先清除寄存器(XOR reg, reg
; 2 个字节)来稍微压缩代码大小,将其用作 reg-regMOV
的源寄存器(它们是每个只有 2 个字节),然后MOV
对那些已经清除了高 16 位的寄存器执行 16 位 s。
在处理具有大量寄存器的 ISA 时,在特定过程的上下文中将一个专用于包含 0 是相对常见的做法。许多 ISA 通过使用专用的零寄存器更进一步。您也可以使用 x86 执行此操作,但考虑到 ISA 的寄存器限制程度,这通常是一种悲观。但是,如果您将优化大小放在首位,那么有时可能会有意义。(再一次,它可能不会,因为它可能会迫使您溢出到内存,并且每次存储和加载都会使代码膨胀至少2 个字节。)
实际上,我敢打赌,在您的代码中还有很多其他地方,您会在指令大小方面挥霍无度,并且可以实现更显着的减少。如果您想审查代码并着眼于减小其大小,请考虑在Code Review上发布一个问题(当然,假设您有工作代码)。
我不确定在什么情况下你会编写代码,节省 2 个字节会很重要。也许您正在编写一个需要容纳在 512 字节以内的引导加载程序?在这种情况下,大多数人所做的是编写一个多阶段引导加载程序,其中第一阶段,即仅限于 512 字节的阶段,只需调用第二阶段,而您没有此类限制。