11.其他技巧:
如果EAX小于80000000h,edx清0:
--------------------------------------------------
1) xor edx, edx ;2 bytes, but faster
2) cdq ;1 byte, but slower
我一直使用cdq,为什么不呢?体积更小...
下面这种情况一般不要使用esp和ebp,使用其他寄存器.
-----------------------------------------------------------
1) mov eax, [ebp] ;3 bytes
2) mov eax, [esp] ;3 bytes
3) mov eax, [ebx] ;2 bytes
交换寄存器中4个字节的顺序?用bswap
---------------------------------------------------------
mov eax, 12345678h ;5 bytes
bswap eax ;2 bytes
;eax = 78563412h now
Wanna save some bytes replacing CALL ?
---------------------------------------
1) call _label_ ;5 bytes
ret ;1 byte
2) jmp _label_ ;2/5 (SHORT/NEAR)
如果仅仅是优化,并且不需要传递参数,请尽量用jmp代替call
比较 reg/mem 时如何节省时间:
------------------------------------------
1) cmp reg, [mem] ;slower
2) cmp [mem], reg ;1 cycle faster
乘2除2如何节省时间和空间?
------------------------------------------------------------
1) mov eax, 1000h
mov ecx, 4 ;5 bytes
xor edx, edx ;2 bytes
div ecx ;2 bytes
2) shr eax, 4 ;3 bytes
3) mov ecx, 4 ;5 bytes
mul ecx ;2 bytes
4) shl eax, 4 ;3 bytes
loop指令
------------------------
1) dec ecx ;1 byte
jne _label_ ;2/6 bytes (SHORT/NEAR)
2) loop _label_ ;2 bytes
再看:
3) je $+5 ;2 bytes
dec ecx ;1 byte
jne _label_ ;2 bytes
4) loopXX _label_ (XX = E, NE, Z or NZ) ;2 bytes
loop体积小,但486以上的cpu上执行速度会慢一点...
比较:
---------------------------------------------------------
1) push eax ;1 byte
push ebx ;1 byte
pop eax ;1 byte
pop ebx ;1 byte
2) xchg eax, ebx ;1 byte
3) xchg ecx, edx ;2 bytes
如果仅仅是想移动数值,用mov,在pentium上会有较好的执行速度:
4) mov ecx, edx ;2 bytes
比较:
--------------------------------------------
1) 未优化:
lbl1: mov al, 5 ;2 bytes
stosb ;1 byte
mov eax, [ebx] ;2 bytes
stosb ;1 byte
ret ;1 byte
lbl2: mov al, 6 ;2 bytes
stosb ;1 byte
mov eax, [ebx] ;2 bytes
stosb ;1 byte
ret ;1 byte
---------
;14 bytes
2) 优化了:
lbl1: mov al, 5 ;2 bytes
lbl: stosb ;1 byte
mov eax, [ebx] ;2 bytes
stosb ;1 byte
ret ;1 byte
lbl2: mov al, 6 ;2 bytes
jmp lbl ;2 bytes
---------
;11 bytes
读取常数变量,试试在指令中直接定义:
-----------------------------
...
mov [ebp + variable], eax ;6 bytes
...
...
variable dd 12345678h ;4 bytes
2) 优化为:
mov eax, 12345678h ;5 bytes
variable = dword ptr $ - 4
...
...
mov [ebp + variable], eax ;6 bytes
呵呵,好久没看到这么有趣的代码了,前提是编译的时候支持代码段的写入属性要被设置.
最后介绍未公开指令SALC,现在的调试器都支持...什么含义呢:就是CF位置1的话就将al置为0xff
------------------------------------------------------------------
1) jc _lbl1 ;2 bytes
mov al, 0 ;2 bytes
jmp _end ;2 bytes
_lbl: mov al, 0ffh ;2 bytes
_end: ...
2) SALC db 0d6h ;1 byte ;)
上一页 [1] [2] [3]