I wrote simple program(was built in release mode(x86)) to practise re skills but I can not understand one part of it.

C++ program:

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);
        wynik = doSub(liczbaA, liczbaB);

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

enter image description here

And my question is: what is happening here?

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

I supposed to see here two instructions like sub/add. Can someone explain me how it's handled here operation +2 and -2?


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
main endp
  • 3
    don't put assembly as an image. Please put some effort and use text. It's easier for everyone – Paweł Łukasik Jul 17 '18 at 5:18
  • 2
    sorry for that, when I will come back home, I will change it – Mroczny Arturek Jul 17 '18 at 7:00
  • 1
    A suggestion for future explorations: submit your code at Godbolt.org where you can see what different compilers produce for the same code. – Jongware Jul 17 '18 at 8:55

0FFFFFFFEh is -2 in decimal format

ecx= is 1 if liczbaA is more than 3 and 0 otherwise

instruction LEA (load effective address) can do special arithmetic operation: a + b*X + Y where a and b are registers, Y is constant and X is 1, 2, 4 or 8.

In your case you calculate: -2+4*ecx or -2+4*(liczbaA>3)

if liczbaA is more than 3 then result is 2 if less then it is -2

  • It make sense. Two questions from my side: 1. "-2 + 4*ecx", is there always add operator(between number and register)? 2. Does "ds:" have special meaning here? or on (x86) can I ignore it? – Mroczny Arturek Jul 17 '18 at 7:29

Release mode optimises. if you want to see simple unoptimised asm blow-by-blow - turn off all optimisations or compile your code in debug mode (not sure the latter will work tho).

The whole segment from

cmp ebx,3


add eax, ecx

looks like the equivalent of the original if with your two functions inlined and the condition flattened into a series of arithmetic operations.

  • A minor note: even when not specifying full optimization, a lot of current compilers already optimize as much as possible in the initial compiling run. Gone are the days you could quite literally "read" the translation of one C instruction in a coherent series of ASM statements. – Jongware Jul 17 '18 at 8:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.