3

这是从(可能)使用 MSVC 创建的 x86 exe 反汇编而来的。
这些循环的任何原因还是它们只是膨胀?

00428D08   |> B9 02000000    MOV ECX,2
00428D0D   |> 33C0           /XOR EAX,EAX
00428D0F   |> 8BF0           |/MOV ESI,EAX
00428D11   |. 48             ||DEC EAX
00428D12   |. 83F8 E9        ||CMP EAX,-17
00428D15   |.^7F F8          |\JG SHORT File.00428D0F
00428D17   |. 49             |DEC ECX
00428D18   |.^75 F3          \JNZ SHORT File.00428D0D

ESI后来在某种跳表中使用,但在我看来,这似乎是一种过于复杂的设置ESI两次的方法

4

1 回答 1

1

如果没有额外的入口点并且没有自修改代码,则可以通过一种独特的方式遍历代码:

mov ecx,2              ; ecx = 2
xor eax,eax            ; eax = 0, ecx = 2, SF = 0, ZF = 0
mov esi,eax            ; eax = 0, ecx = 2, esi = 0, no changes to flags
dec eax                ; eax = 0xFFFFFFFF, ecx = 2, esi = 0, SF = 1, ZF = 0
cmp eax,-17            ; OF = 0, SF = 1, ZF = 0
jg SHORT File.00428D0F ; jump if (SF==OF and ZF==0) -> jump.

mov esi, eax; eax= 0xFFFFFFFF, ecx= 2, esi= 0xFFFFFFFF ... 16 次内循环后情况如下:

mov esi,eax            ; eax = -16, ecx = 2, esi = -16
dec eax                ; eax = -17, ecx = 2, esi = -16, SF = 1, ZF = 0
cmp eax,-17            ; OF = 0, SF = 0, ZF = 1
jg SHORT File.00428D0F ; jump if (SF==OF and ZF==0) -> no jump.
dec ecx                ; eax = -17, esi = -16, ecx = 1, SF = 0, ZF = 0

外循环是微不足道的。如果确定除了 00428D08(这段代码的开头)没有其他入口点mov ecx,2,即代码没有从其他地方修改并且这段代码没有用作数据,则可以将代码替换为:

如果在此代码结束后使用标志值:

mov eax,-17
cmp eax,-17
mov ecx,1
dec ecx
mov esi,-16

如果标志的值不重要:

mov eax,-17
mov ecx,0
mov esi,-16
于 2012-09-07T22:41:08.243 回答