Объясните ассемблерный листинг плиз :)

Тема в разделе "WASM.BEGINNERS", создана пользователем igrock, 16 фев 2008.

  1. igrock

    igrock New Member

    Публикаций:
    0
    Регистрация:
    27 янв 2008
    Сообщения:
    29
    Добрый день.
    Есть исходник file.c:

    main(){}

    компилю gcc -S file.c
    открываю листинг file.s

    _main:
    pushl %ebp
    movl %esp, %ebp
    subl $8, %esp
    andl $-16, %esp
    movl $0, %eax
    addl $15, %eax
    addl $15, %eax
    shrl $4, %eax
    sall $4, %eax
    movl %eax, -4(%ebp)
    movl -4(%ebp), %eax
    call __alloca
    call ___main
    leave
    ret

    Откуда столько кода, и что он означает, это что то вроде шапки, но что она делает?

    ===============================================================

    компилю с оптимизацией gcc -S -O3 file.c

    _main:
    pushl %ebp
    movl $16, %eax
    movl %esp, %ebp
    subl $8, %esp
    andl $-16, %esp
    call __alloca
    call ___main
    leave
    ret

    Все равно много кода, что вырезала оптимизация, почему не все?

    З.Ы. Как оформить ассемблерную вставку для gcc? __asm{inc cx}; не работает :|
     
  2. Gais

    Gais New Member

    Публикаций:
    0
    Регистрация:
    28 мар 2007
    Сообщения:
    68
    В gcc скорее всего используется синтаксис AT&T, (например nasm) поищи в справочнике
     
  3. Xerx

    Xerx Алексей

    Публикаций:
    0
    Регистрация:
    17 фев 2005
    Сообщения:
    528
    Адрес:
    Russia
    igrock
    Вместо __asm{inc cx} пиши __asm{"inc %cx%"}
     
  4. igrock

    igrock New Member

    Публикаций:
    0
    Регистрация:
    27 янв 2008
    Сообщения:
    29
    Вот так работает asm("inc %cx"); =)

    Ну дак как на счет листинга, понимаю неохота разжовывать, но всетаки ^_^
     
  5. KeSqueer

    KeSqueer Сергей

    Публикаций:
    0
    Регистрация:
    19 июл 2007
    Сообщения:
    1.183
    Адрес:
    Москва
    movl $0, %eax
    addl $15, %eax
    addl $15, %eax
    shrl $4, %eax
    sall $4, %eax

    тут написано: eax=((0+15+15)/2^4)*2^4 что эквивалентно eax=16. Поэтому вместо вышеприведенного кода получаем: movl $16, %eax

    ---------
    movl %eax, -4(%ebp)
    movl -4(%ebp), %eax

    тут написано: [ebp-4] = eax; eax = [ebp-4]. Это тоже самое, что и b=a; a=b; но b потом нигде не используется. Понятное дело, что компилятор это пропустит, что он собственно и сделал.

    ------------
    pushl %ebp
    movl %esp, %ebp
    subl $8, %esp
    andl $-16, %esp
    ...
    leave
    ret

    тут написан вход и выход в процедуру. Третья строка "выделяет" стековую память под переменную b, которая не используется. Четвертая для выравнивания стековой памяти по 16 байтной границе.
    Т.к. переменная b не используется, то это все кроме ret я бы убрал и оставил вот в таком виде:

    _main:
    movl $16, %eax
    call __alloca
    call ___main
    retn
     
  6. igrock

    igrock New Member

    Публикаций:
    0
    Регистрация:
    27 янв 2008
    Сообщения:
    29
    Хотелось бы понять почему компилятор такой тривиальный код превращает, в большой набор ненужных в принципе ассемблерных строчек?
     
  7. crypto

    crypto Active Member

    Публикаций:
    0
    Регистрация:
    13 дек 2005
    Сообщения:
    2.533
    igrock
    Дык компилятор создает так называемый "startup-code", из которого, собственно и вызывается функция main. В зависимости от того, под какую платформу компилируется код, стартовый код будет выглядеть по-разному.
    К примеру, если ты пишешь консольное приложение, то компилятор передаст твоей функции main ряд аргументов (int argc, char *argv[], ...). В твоем случае, поскольку у тебя аргументы в функцию main не передаются, и код достаточно простой (я, правда, особенностей используемого тобой компилятора не знаю, говорю с общих позиций). Если ты посмотришь стартовый код в программах для Win32, то увидишь, что кода больше, так как операционной системе нужно проделать определенную работу (создать среду исполнения) прежде чем будет вызвана функция WinMain.
    В Билдере и Дельфи стартовый код больше, поскольку требуется совершить еще больше действий (инициализация библиотек Борланда, загрузка ресурсных строк и т.д.).
     
  8. SII

    SII Воин против дзена

    Публикаций:
    0
    Регистрация:
    31 окт 2007
    Сообщения:
    1.483
    Адрес:
    Подмосковье
    igrock

    Дополню crypto :)

    Хотя в определённых случаях стартовый код в полном объёме не нужен (данная программа -- именно такой случай), но у компилятора либо вовсе нет разных вариантов стартового кода (и тогда он одинаковый для всех), либо вариаций сравнительно мало -- вот он и лепит кучу лишнего.