2014-10-09 64 views
1

我想了解一些反汇编的代码,但我无法理解这里发生了什么。你能解释它的作用吗?无法理解反汇编代码,有什么想法?

sub  ecx, edi  
sar  edx, 1 
mov  eax, 2AAAAAABh 
imul ecx 
mov  eax, edx 
shr  eax, 31 
add  eax, edx 
test eax, eax 
jle  ... 

ecxedxedi包含此代码某种输入值。

我只能假设最后两行对可能像if(eax <= 0) goto ...那样工作,但我不确定。

+0

'ecx','edx','edi'和'eax'是[寄存器(HTTPS: //en.wikipedia.org/wiki/X86_assembly_language)。 'test'指令设置'jle'这样的条件指令使用的'cflags'。 – Jason 2014-10-09 05:54:49

+0

我的意思是,'ecx','edx'和'edi'寄存器包含这个代码块的输入值。 – 2014-10-09 05:56:01

+0

'ecx'通常是一个循环计数寄存器,'edi'是一个目标寄存器,所以它可能在一个数组上循环。您需要确定每个寄存器的用途,以确定代码实际上在做什么。 – Jason 2014-10-09 06:09:15

回答

1

我认为这是检查溢出的计算未知目的。

sub ecx,edi  ; ecx = ??? no idea where these come from or what they mean 

sar edx,1   ; edx changed but value is lost, as are flags, no idea why this is done 

mov eax,2AAAAAABh ; eax = 715827883, no idea why this number is important 
imul ecx   ; edx:eax = (original ecx-edi) * 715827883 

mov eax,edx  ; eax = high-dword of product 
shr eax,31  ; eax = high-bit of high-dword of product 
add eax,edx  ; eax = high-dword of product + high-bit of high-dword of product 
        ; assuming 0 <= ecx < ~10, eax will be zero if the result did not carry into edx 
        ; assuming ~-10 < ecx < 0, eax will be zero if the result did not carry into edx 
        ; therefore, |ecx|<~10, eax = overflow-from-multiplication 

test eax,eax 
jle ...   ; taken if eax=0 or SF=OF 

我不确定“sign flag = overflow flag”部分的意义是什么意思。对于小的ecx值可能不会发生。

+0

而我仍然不知道这段代码的目的,但无论如何,谢谢你的解释。 – 2014-10-09 09:10:04

2

2AAAAAAB是一个“幻数”。序列

MOV EAX, 2AAAAAABh 
IMUL dividend 
MOV EAX, dividend 
SHR EAX, 31 
ADD EDX, EAX 

是这个师签署不使用IDIV

EDX = dividend/6

指令sar edx, 1是没用的,因为EDXimul ecx被覆盖。在C中,发布的序列可以写为

if ((ECX-EDI)/6 > 0) { ... } else ("jle") { ... }

+0

multiplicative inverses的全部细节:[为什么GCC在实现整数除法时使用奇数乘法?](https://stackoverflow.com/questions/41183935/why-does-gcc-use-multiplication-by-a-陌生的号码,在-实施-整数迪维)。这个问题不是相当重复的,因为它也询问了分支,并有神秘的死亡'sar'。在反编译的代码中非常令人惊讶。可能它不是编译器生成的或被错误复制的。 – 2018-02-04 13:06:35

1

的代码是一个优化的分割的一种形式,在该代码中使用的常数是Wagstaff prime