вызов функции

Тема в разделе "WASM.ASSEMBLER", создана пользователем k_dmitry, 29 июл 2008.

  1. k_dmitry

    k_dmitry New Member

    Публикаций:
    0
    Регистрация:
    29 июл 2008
    Сообщения:
    9
    помогите разобраться -

    есть такой C код :
    Код (Text):
    1. void foo(void (*f)(void)) { f(); }
    у меня gcc переводит в асм это примерно так -
    Код (Text):
    1.         pushl   %ebp
    2.         movl    %esp, %ebp
    3.         subl    $8, %esp
    4.         movl    8(%ebp), %eax
    5.         call    *%eax
    6.         leave
    7.         ret
    я не могу понять зачем там "sub 8, esp", если ее убрать вылетает сегфолт
    появляется она только если есть вызов функции (необязательно через указатель)

    да и если что - у меня Мак, может это из-за этого, я не знаю просто че на остальных платформах получается в асме
     
  2. zhindos

    zhindos New Member

    Публикаций:
    0
    Регистрация:
    10 июл 2008
    Сообщения:
    142
    k_dmitry

    В функциях команды типа:

    Код (Text):
    1. push    ebp
    2. mov     ebp, esp
    3. sub     esp, n
    это формирование стекового кадра (stack frame) для локальных переменных; иногда применяют
    Код (Text):
    1. enter n, 0
    (второй операнд необязательно 0), который выполняет все те же действия.

    ЗЫ. Не думал, что на wasm-е в разделе ASSEMBLER увижу подобный пост :))
    ЗЗЫ. Ох уж этот зверский AT&T синтаксис :)
     
  3. k_dmitry

    k_dmitry New Member

    Публикаций:
    0
    Регистрация:
    29 июл 2008
    Сообщения:
    9
    zhindos
    так тут же нет локальных переменных. если бы было так, то можно было бы безболезненно убрать, а оно не убирается(

    листинг полный я ничего не укорачивал
     
  4. zhindos

    zhindos New Member

    Публикаций:
    0
    Регистрация:
    10 июл 2008
    Сообщения:
    142
    k_dmitry

    Я очень не люблю синтаксис, который предложила когда-то небезызвестная фирма из 3-х букв,но смею предположить, что страшная фича:
    Код (Text):
    1. movl    8(%ebp), %eax
    на самом деле не что иное, как:
    Код (Text):
    1. mov    eax, dword ptr [ebp]
    (сбивает с толку 8-ка, но повторяю - i hate AT&T syntax!)
    А вот теперь и подумай, с какой области стека ты читаешь что-либо в eax, если убрать то, что ты хотел убрать???
     
  5. wsd

    wsd New Member

    Публикаций:
    0
    Регистрация:
    8 авг 2007
    Сообщения:
    2.824
    zhindos
    нет это
    Код (Text):
    1. mov    eax, dword ptr [ebp+8]
     
  6. zhindos

    zhindos New Member

    Публикаций:
    0
    Регистрация:
    10 июл 2008
    Сообщения:
    142
    fuck AT&T :)

    wsd,
    Thanks
     
  7. k_dmitry

    k_dmitry New Member

    Публикаций:
    0
    Регистрация:
    29 июл 2008
    Сообщения:
    9
    zhindos
    Код (Text):
    1. movl 8(%ebp), %eax
    ~
    Код (Text):
    1. movl eax, [ebp + 8]
    это берется параметр ф-ии. после "sub esp, 8" нам доступны [ebp-4] и [ebp-8] a они нигде не используются.

    тут вся загвостка в call, код ниже работает и возвращает правильный результат

    Код (Text):
    1.         pushl   %ebp
    2.         movl    %esp, %ebp
    3.         movl    8(%ebp), %eax
    4.         leave
    5.         ret
    ---
    че-то я потыкал, и вроде как сегфолт вылетает только если в ф-ии, которая через указатель передается, есть вызовы ф-ий из стд библиотеки, ну там printf, malloc...непонятно ниче. а может кто-нибудь посмотреть в линуксе также? в смысле асм такой же получается?
     
  8. k_dmitry

    k_dmitry New Member

    Публикаций:
    0
    Регистрация:
    29 июл 2008
    Сообщения:
    9
    ура! я нашел ответ))
    оказывается у Маков с Интелом хитрая calling convention, они требуют чтобы перед любым call стэк был выровнен по 16 байт, и в моем примере в стэк перед вызовом той ф-ии был push адреса возврата (4 байта) потом EBP (опять 4), ну и потом вычиталось 8 чтоб было все ровно)
     
  9. zhindos

    zhindos New Member

    Публикаций:
    0
    Регистрация:
    10 июл 2008
    Сообщения:
    142
    Ипонуццо :)))
    У меня похожая мысль мелькала, но я подумал, что это полный бред...(если б хотя бы 8)