Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ionic-framework/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 如何简化程序集平移右移32异或绝对数和值_Assembly_Xor_Shift_Absolute Value_Ida - Fatal编程技术网

Assembly 如何简化程序集平移右移32异或绝对数和值

Assembly 如何简化程序集平移右移32异或绝对数和值,assembly,xor,shift,absolute-value,ida,Assembly,Xor,Shift,Absolute Value,Ida,我不知道最初的代码,但我不相信右移和abs有这么复杂 下面是重命名的反编译IDA PRO代码的样子 char Ship; //Could be 0-7 (8 is reversed for special purpose) char NewShip = 1; //Could be 0-7 (8 is reversed for special purpose) short Frequency = 0; //This could be from 0 to 9999 bool NumberToFre

我不知道最初的代码,但我不相信右移和abs有这么复杂

下面是重命名的反编译IDA PRO代码的样子

char Ship; //Could be 0-7 (8 is reversed for special purpose)
char NewShip = 1; //Could be 0-7  (8 is reversed for special purpose)
short Frequency = 0; //This could be from 0 to 9999
bool NumberToFrequency = true;

Frequency = GetNextFrequencyToJoin(player->MyArena);
if ( NumberToFrequency )
{ //TODO: maybe the below is just Frequency % 7; ?
  NewShip = (((unsigned long)Frequency >> 32) ^ abs(Frequency) & 7) - ((unsigned long)Frequency >> 32);
  Ship = NewShip;
} else {
  Ship = NewShip;
}
这是一个表意文字测试

似乎
NewShip=abs(频率)&7)是我真正需要的一切,似乎我通过循环测试了所有的可能性,从不出错

另一个反编译器给了我这个结果

 asm("cdq ");
 NewShip = ((Var1 ^ Var2) - Var2 & 7 ^ Var2) - Var2;
它并没有右移,或者对我来说仍然是陌生的,可能显示了绝对数是如何工作的,并且仍然不知道右移32是从哪里来的

NumberToFrequency
假设做的是使频率与船舶相同,但当然频率超过7,所以剩余的值仍应转换为船舶值,所以我假设它只是7的模数
%

但是为什么这么复杂的代码可能意味着完全不同的东西呢?我只是问代码是什么意思。我将在下面添加汇编代码。我甚至在下面的装配中找不到右移32档,我很确定它在同一个地方

.text:0040DD3A                 mov     ecx, [ebp+1Ch]  ; arena
.text:0040DD3D                 call    GetNextFrequencyToJoin
.text:0040DD42                 mov     ecx, [ebp+1Ch]
.text:0040DD45                 mov     si, ax
.text:0040DD48                 mov     [esp+220h+var_20C], si
.text:0040DD4D                 cmp     [ecx+1ACCEh], ebx
.text:0040DD53                 jz      short loc_40DD98
.text:0040DD55                 movsx   eax, si
.text:0040DD58                 cdq
.text:0040DD59                 xor     eax, edx
.text:0040DD5B                 sub     eax, edx
.text:0040DD5D                 and     eax, 7
.text:0040DD60                 xor     eax, edx
.text:0040DD62                 sub     eax, edx
.text:0040DD64                 mov     [esp+220h+var_20F], al
编辑:
我自己找到了答案,似乎那些shift 32
>32
对于一些旧的C编译支持来说是无用的垃圾,它们的类型与32位DWORD或类似的废话相匹配。

我想我已经找到了答案,我使用的IDA-PRO反编译器似乎在所有地方生成了这些右移32的
>32
,在我看到的所有情况下,都使用了
abs()
函数,它似乎是绝对数函数的无用包装器

我找到了一些例子

//1
((((unsigned long)i >> 32) ^ abs(i)) - ((unsigned long)i >> 32))
//2
(((unsigned long)encryption->field_25E >> 32) ^ abs(encryption->field_25E)) - ((unsigned long)encryption->field_25E >> 32);
//3
((((unsigned long)i >> 32) ^ abs(i)) - ((unsigned long)i >> 32))
//4
(((unsigned long)(v104->field_A8 + 1) >> 32) ^ abs(*((unsigned char*)&(v104->field_A8)) + 1) & 7) - ((unsigned long)(v104->field_A8 + 1) >> 32);
//5
(((unsigned long)v11 >> 32) ^ abs(v11)) - ((unsigned long)v11 >> 32);
//6
(((unsigned long)v4->field_262 >> 32) ^ abs(v4->field_262)) - ((unsigned long)v4->field_262 >> 32)
//7
(((unsigned long)v18 >> 32) ^ abs(v18)) - ((unsigned long)v18 >> 32);
//8 (not refactored yet).
((((unsigned long)*(unsigned int *)(v1 + 610) >> 32) ^ abs(*(unsigned int *)(v1 + 610))) - ((unsigned long)*(unsigned int *)(v1 + 610) >> 32)
你也可以在另外一个地方看到这些
>32
,我已经知道这是从研究中优化出来的,看起来更不一样

像这样疯狂的东西(我用正则表达式工具修复了它)


用于将其转换回
/60
的方程式在上讨论。移位并非无用。这是一种平庸的逻辑,Hexray在其c反汇编中没有复制

.text:0040DD55                 movsx   eax, si
.text:0040DD58                 cdq
.text:0040DD59                 xor     eax, edx
.text:0040DD5B                 sub     eax, edx
.text:0040DD5D                 and     eax, 7
.text:0040DD60                 xor     eax, edx
.text:0040DD62                 sub     eax, edx
是重要的代码
EDX:EAX
SI
的符号扩展版本,因此
EDX
为0或-1。
xor
要么保持
eax
不变,要么将其反转,
sub
保持不变,要么添加一个,以此类推:

if (si < 0) {
    eax = ~si;
    eax += 1;
    eax &= 0x7;
    eax = ~eax;
    eax += 1;
} else {
    eax = si & 0x7;
}
或者简言之

eax = (abs(si) & 0x7) * sign(si);
或使用带符号的模运算符

al = si % 8;

哈哈,如果可以的话,你能不能简化一下,我不知道发生了什么,老实说,如果不占用你太多时间的话,我会很感激的。怀疑这里是否使用了分支它可能是abs函数本身的源代码?那么这是否意味着它实际上是
,而不是
&
在这里使用?@user3435580抱歉,我甚至没有看到这一点。是的,它实际上是一个模数
al=si%8
使用有符号的
运算符。那么0x1007是位掩码还是什么?以前从没见过这样的。你认为它原本是什么样子的干净<代码>新闻信息=abs(频率)和7)
似乎给出了相同的精确结果,但这也是基于您所说的十六进制射线反编译错误。@user3435580 sry,我一时糊涂了(使用0x1007掩码)。现在应该是正确的。旁注:[ida]是首选标记([ida]和[ida pro]应该是同义词;请参阅:)
eax = (abs(si) & 0x7) * sign(si);
al = si % 8;