gpt4 book ai didi

assembly - 如何简化汇编翻译右移 32 异或绝对数和值

转载 作者:行者123 更新时间:2023-12-01 16:49:02 25 4
gpt4 key购买 nike

我不知道原始代码,但我不相信右移和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;
}

这是一个 IDEOne 测试 http://ideone.com/Q2bEjU

似乎NewShip = abs(Frequency) & 7);是我真正需要的,似乎我通过循环测试了所有可能性,它永远不会搞砸。

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

 asm("cdq ");
NewShip = ((Var1 ^ Var2) - Var2 & 7 ^ Var2) - Var2;

其中没有右移或任何对我来说仍然看起来陌生的东西,可能显示了绝对数字是如何工作的,但仍然不知道右移 32 来自哪里。

NumberToFrequency 的作用是使频率与船舶相同,但频率当然会超过 7,因此其余值仍应转换为船舶值,所以我假设它只是一个模数%(共 7 个)。

但是为什么这么复杂的代码可能意味着完全不同的东西呢?我只是想问一下代码是什么意思我将在下面添加汇编代码。我什至在下面的程序集中找不到 Shift right 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 或类似的垃圾。

最佳答案

轮类并非毫无用处。这是一种无银行逻辑形式,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:EAXSI 的符号扩展版本,所以EDX是 0 或 -1。 xor要么离开 eax不受影响或反转它,sub保持不变或总共添加一个等等:

if (si < 0) {
eax = ~si;
eax += 1;
eax &= 0x7;
eax = ~eax;
eax += 1;
} else {
eax = si & 0x7;
}

第一个分支仍然可以简化,但我把它留给你......

<小时/>

更新

分支仅在 si<0 上有所不同已经暗示了正在发生的事情。序列eax = ~si; eax += 1;可以理解为two's-complement ,因此插入我们对这个补集的知识,我们得到

if (si < 0) {
eax = -1 * si;
eax &= 0x7;
eax *= -1;
} else {
eax = si & 0x7;
}

或者简而言之

eax = (abs(si) & 0x7) * sign(si);

或者使用有符号模运算符

al = si % 8;

关于assembly - 如何简化汇编翻译右移 32 异或绝对数和值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23309881/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com