Сложение в GCC

Тема в разделе "WASM.RESEARCH", создана пользователем Arman, 19 июн 2008.

  1. Arman

    Arman New Member

    Публикаций:
    0
    Регистрация:
    13 май 2008
    Сообщения:
    13
    Компилятор: MinGW 5.1.4. Компилятор запускал без ключей.
    Исходный текст программы:
    Код (Text):
    1. #include <stdio.h>
    2.  
    3. main()
    4. {
    5.     int a=5,b=6;
    6.     int sum=a+b;
    7.     printf("Summary is: %d\n",sum);
    8.     return 0;
    9. }
    Полученный дизассемблерный листинг для процедуры main:
    Код (Text):
    1. main proc near
    2.  
    3. var_18= dword ptr -18h
    4. var_14= dword ptr -14h
    5. var_10= dword ptr -10h
    6. c = dword ptr -0Ch
    7. b = dword ptr -8
    8. a = dword ptr -4
    9.  
    10.   push  ebp
    11.   mov   ebp, esp
    12.   sub   esp, 18h                                         ; выделение памяти под локальные переменные
    13.   and   esp, 0FFFFFFF0h                               ; (1)
    14.   mov   eax, 0
    15.   add   eax, 0Fh
    16.   add   eax, 0Fh
    17.   shr   eax, 4
    18.   shl   eax, 4
    19.   mov   [ebp+var_10], eax
    20.   mov   eax, [ebp+var_10]
    21.   call  sub_401860
    22.   call  sub_4013E0                                     ; (2)
    23.   mov   [ebp+a], 5                                      ;a=5
    24.   mov   [ebp+b], 6                                      ;b=6
    25.   mov   eax, [ebp+b]
    26.   add   eax, [ebp+a]
    27.   mov   [ebp+c], eax ;c = a + b
    28.   mov   eax, [ebp+c]
    29.   mov   [esp+18h+var_14], eax
    30.   mov   [esp+18h+var_18], offset aSummaryIsD ; "Summary is: %d\n"
    31.   call  printf                                               ; printf("Summary is: %d\n",c)
    32.   mov   eax, 0
    33.   leave
    34.   retn
    35. main endp
    Объясните, пожалуйста, код от (1) до (2).
     
  2. reverser

    reverser New Member

    Публикаций:
    0
    Регистрация:
    27 янв 2004
    Сообщения:
    615
    Приведи код sub_401860 и sub_4013E0. Или лучше бинарник выложи. На первый взгляд - просто скомпилировано вообще без какой-либо оптимизации.
     
  3. Arman

    Arman New Member

    Публикаций:
    0
    Регистрация:
    13 май 2008
    Сообщения:
    13
    Да, это без оптимизации.
    Код (Text):
    1. sub_401860 proc near            ; CODE XREF: main+20p
    2.   push  ecx
    3.   mov   ecx, esp
    4.   add   ecx, 8
    5.  
    6. loc_401866:            
    7.   cmp   eax, 1000h
    8.   jb    short loc_40187D
    9.   sub   ecx, 1000h
    10.   or    dword ptr [ecx], 0
    11.   sub   eax, 1000h
    12.   jmp   short loc_401866
    13. ; ---------------------------------------------------------------------------
    14.  
    15. loc_40187D:            
    16.   sub   ecx, eax
    17.   or    dword ptr [ecx], 0
    18.   mov   eax, esp
    19.   mov   esp, ecx
    20.   mov   ecx, [eax]
    21.   mov   eax, [eax+4]
    22.   jmp   eax
    23. sub_401860 endp
    Код (Text):
    1. sub_4013E0 proc near            ; CODE XREF: sub_401150+D5p main+25p
    2.   push  ebp
    3.   mov   eax, ds:dword_404020
    4.   mov   ebp, esp
    5.   test  eax, eax
    6.   jz    short loc_4013F0
    7.   pop   ebp
    8.   retn
    9. ; ---------------------------------------------------------------------------
    10.   align 10h
    11.  
    12. loc_4013F0:             ; CODE XREF: sub_4013E0+Aj
    13.   pop   ebp
    14.   mov   eax, 1
    15.   mov   ds:dword_404020, eax
    16.   jmp   short sub_401380
    17. sub_4013E0 endp
    Извините, но файл прикрепить не могу, поэтому привожу листинги.
     
  4. q_q

    q_q New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2003
    Сообщения:
    1.706
    Arman
    sub esp, 18h ; выделение памяти под локальные переменные
    Не только, тут место и для аргументов, в данном случае, printf'а.

    and esp, 0FFFFFFF0h ; (1)
    gcc хочет чтобы указатель стека был выровнен по ближайшей (нижней) 16-тибайтной границе.

    call sub_4013E0 ; (2)
    Это вызов viod __main(void). Например, вот что по этому поводу написано в GNU Compiler Collection Internals For gcc version 4.4.0 (pre-release): "The __main function is defined in ‘libgcc2.c’ and runs the global constructors." Полный текст смотри/ищи в gccint.pdf).

    ps чтобы увидеть __main вместо sub_4013E0 достаточно указать компилятору, генерировать asm-листинг при помощи ключа -S.