关于数据段的Lea指令

逆向工程 艾达 拆卸
2021-06-27 11:49:05

我写了一个简单的程序(以发布模式(x86)构建)来练习重新技能,但我无法理解其中的一部分。

C++程序:

int doSub(int a, int b) 
{
    int result = a + b;
    result -= 2;
    return result;
}

int doSum(int a, int b)
{
    int result = a + b;
    result += 2;
    return result;
}

int main(int argc, char** argv)
{      
    int wynik = 0;
    int liczbaA = atoi(argv[1]);
    int liczbaB = atoi(argv[2]);

    if (liczbaA > 3)
    {
        wynik = doSum(liczbaA, liczbaB);
    }
    else
    {
        wynik = doSub(liczbaA, liczbaB);
    }

    std::cout << "Result" << wynik;
    return 0;
}

在此处输入图片说明

我的问题是:这里发生了什么?

lea     ecx, ds:0FFFFFFFEh[ecx*4] ; ??

我应该在这里看到两个指令,如 sub/add。有人能解释一下这里是如何处理 +2 和 -2 操作的吗?

@编辑

loc_401052:
mov     edi, [ebp+argv]
push    dword ptr [edi+4] ; Str
call    ds:__imp__atoi
add     esp, 4
mov     ebx, eax
push    dword ptr [edi+8] ; Str
call    ds:__imp__atoi
xor     ecx, ecx
add     esp, 4
add     eax, ebx
mov     edx, offset aResult ; "Result"
cmp     ebx, 3
setnle  cl
lea     ecx, ds:0FFFFFFFEh[ecx*4]
add     eax, ecx
push    eax
push    ecx
mov     ecx, ds:__imp_?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A ; std::basic_ostream<char,std::char_traits<char>> std::cout
call    std__operator___std__char_traits_char___
add     esp, 4
mov     ecx, eax
call    ds:__imp_??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV01@H@Z ; std::basic_ostream<char,std::char_traits<char>>::operator<<(int)
pop     edi
xor     eax, eax
pop     ebx
mov     esp, ebp
pop     ebp
retn
main endp
2个回答

发布模式优化。如果您想逐一查看简单的未优化的 asm - 关闭所有优化或在调试模式下编译您的代码(不确定后者是否能正常工作)。

全段从

cmp ebx,3

add eax, ecx

看起来与原始if等效,其中两个函数内联并且条件扁平化为一系列算术运算。

0FFFFFFFEh-2十进制格式

如果 liczbaA 大于 3,则 ecx= 为 1,否则为 0

指令LEA(加载有效地址)可以做特殊的算术运算:a + b*X + Y其中ab是寄存器,Y是常数,X是1、2、4或8。

在您的情况下,您计算: -2+4*ecx-2+4*(liczbaA>3)

如果 liczbaA 大于 3,则结果为 2,如果小于则为 -2