【发布时间】:2017-05-29 01:17:23
【问题描述】:
我正在编写一些非常严格的 ASM 代码。
注意这组由 NASM 生成的操作码:
8AA4241C020000 mov ah,[esp+0x21c]
还有类似的:
051C020000 add eax,0x21c ; 4 extra 0's!
8D84241C020000 lea eax,[esp+0x21c] ; Brutal!
有什么方法可以与处理器通信,您打算将 15 位偏移量应用于 32 位寄存器,并让它自己找出 0 填充?
我一直在梳理https://c9x.me/x86/html/file_module_x86_id_176.html 以获得一些指导。这里或那里额外的 2 个字节真的会救我的命!
也接受:
重写语句以使其更小的替代方法,最终我在这种情况下要做的是:
mov eax,[esp+0x21c]
push eax
如果有办法手动对其进行编码以使其超小,我很乐意看到这种技术。
【问题讨论】:
-
上面有一个 LEA 示例 ;)
-
处理器手册告诉您什么是可用的。仅 16 位寄存器支持 16 位偏移。不确定您对手动编码的含义。这不是你可以随便编造的东西。
-
您可以将寄存器的上部归零 (
xor ebx, ebx),然后将 16 位值移入 (mov bx, 21c- 注意:不使用ebx) 并根据需要使用 (add eax, ebx)。 xor 不是免费的,但是如果您多次执行此技巧... -
在某些模式下,某些指令有符号扩展位。使用 16 位寄存器肯定有效,但您还必须先将它们异或以将它们“添加”到 32 位寄存器。
-
如果你想用速度换取空间,你可以使用一些更小但更慢的指令,如
loop、enter、leave... 或将mov eax, -1替换为or eax, 0xFFFFFFFF。旧软件也通过自我修改代码来节省内存,或者将一些代码字节作为常量重用。更多提示Agner Fog's optimization guide for x86 platforms - 10. Optimizing for size
标签: assembly compiler-construction x86 nasm opcodes