Ругань fasm'a

Тема в разделе "WASM.BEGINNERS", создана пользователем zukalo, 22 окт 2008.

  1. zukalo

    zukalo New Member

    Публикаций:
    0
    Регистрация:
    22 окт 2008
    Сообщения:
    20
    Fasm выдаёт ошибку:

    flat assembler version 1.67.14 (1014684 kilobytes memory)
    code.asm [85]:
    invoke FF, [dta], [dtb], [dtc], [dtd], dword [edi+00*4]
    , 07, 0d76aa478h
    D:\coding\fasm v1.67.14\INCLUDE\win32ax.inc [42] invoke [1]:
    \common call [proc] \}
    error: operand size not specified.

    Ф-ция объявлена так:
    proc FF dta,dtb,dtc,dtd,x,s:byte,t

    Что я только туда не вставлял! Смиренно прошу о помощи :)
     
  2. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    zukalo
    Вам стоит научиться различать stdcall и invoke.
     
  3. zukalo

    zukalo New Member

    Публикаций:
    0
    Регистрация:
    22 окт 2008
    Сообщения:
    20
    Почитал доки фасма, там так написано:
    "The invoke macro does the same, however it calls the procedure indirectly, through the pointer labelled by the first argument."

    invoke MessageBox,0,szText,szCaption,MB_OK
    stdcall [MessageBox],0,szText,szCaption,MB_OK

    Вот и вся разница, как я понимаю. И как это относится к моей ошибке?
     
  4. twgt

    twgt New Member

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    1.494
    потому что получается
    invoke FF, [dta].....
    меняется на
    stdcall [FF], [dta].......
    Вот и подумайте как это относится.
     
  5. zukalo

    zukalo New Member

    Публикаций:
    0
    Регистрация:
    22 окт 2008
    Сообщения:
    20
    Заставил работать через Stdcall так:
    stdcall dword FF, ...

    Всё же было бы интересно узнать, как вызвать через invoke?
    Насколько я понимаю invoke работает со списком указателей, обычно через import, если с импортом работать. А как свой объявить?

    Или хотя бы в какой доке искать подскажите, те что с фасмом идут я прочитал.
     
  6. dead_body

    dead_body wasm.ru

    Публикаций:
    0
    Регистрация:
    3 сен 2004
    Сообщения:
    603
    Адрес:
    Украина;г.Харьков;г.Н.Каховка
    zukalo
    invoke - для вызова функций
    stdcall - для вызова процедур

    invoke a = call [a]
    stdcall a = call a

    Вот и вся разница.
     
  7. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    dead_body
    Фу, какое ужасное объяснение.
    Во-первых, AFAIK разница между функциями и процедурами состоит в том, что первые возвращают значение, а вторые нет.
    Во-вторых, эта разница есть только в языках высокого уровня. В асме (и, например, си) это одно и то же.
    В-третьих, это здесь вообще не причём. stdcall - вызов по адресу функции, invoke - вызов по указателю на адрес функции.
    zukalo
    А зачем? У вас есть прямой указатель на функцию. Зачем извращаться и класть этот указатель куда-то в память, чтобы по адресу этой памяти вызывать функцию? (собственно в этом вопросе и содержится ответ на Ваш вопрос)
    Для таблицы импорта ясно, зачем так сделано: на стадии компиляции адреса импортируемых функций не известны. Но взамен известны адреса, куда адреса этих функций будут положены загрузчиком. Поэтому и используется invoke. Для своих функций с конвенцией вызова stdcall используйте stdcall, пока нет необходимости в хранении указателей на фукнции в памяти.
     
  8. zukalo

    zukalo New Member

    Публикаций:
    0
    Регистрация:
    22 окт 2008
    Сообщения:
    20
    Всем спасибо за отзывы.

    Насчёт импорта то я понимаю, но дело в том, что через invoke у меня не получается вызвать мою процедуру! invoke FF никак не работает!
    Так почему же не работает, если разницы в данном случае никакой?
     
  9. _basmp_

    _basmp_ New Member

    Публикаций:
    0
    Регистрация:
    10 июл 2005
    Сообщения:
    2.939
    зачем вообще эти инвоке и стдкалл? Почему не писать все через калл? Прога станет интереснее и вопросов таких не будет.
     
  10. GoldFinch

    GoldFinch New Member

    Публикаций:
    0
    Регистрация:
    29 мар 2008
    Сообщения:
    1.775
    а еще лучше написать свои инвок и стдколл, в которых ты будеш 100% разбираться
     
  11. zukalo

    zukalo New Member

    Публикаций:
    0
    Регистрация:
    22 окт 2008
    Сообщения:
    20
    Дак через invoke быстрее, удобнее да и принято как-то)
     
  12. GoldFinch

    GoldFinch New Member

    Публикаций:
    0
    Регистрация:
    29 мар 2008
    Сообщения:
    1.775
    осталось только узнать как он работает =\
     
  13. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    zukalo
    Вы издеваетесь. У меня два варианта.
    Вариант первый: повторить уже написанное.
    Вариант второй: рекомендовать Вам перечитывать посты с первого по седьмой включительно до полного просветления.
    А что ж Вас не смущает, что Вы Вашу процедуру через add вызвать не можете?
    1) Чем быстрее? На один символ короче что ли?
    2) Что значит "удобнее"? Положение клавиш на клавиатуре благоприятнее?
    3) Кем "принято"?
     
  14. Osen

    Osen Рие

    Публикаций:
    0
    Регистрация:
    5 апр 2008
    Сообщения:
    283
    Адрес:
    Париж
    zukalo
    Если уж вам очень хочется вызывать вашу процедуру через INVOKE, то сделайте следующее.

    1) Объявите DWORD, в который положите адрес вашей FF:
    Код (Text):
    1. ...
    2. pFF dd 0
    3. ...
    4. mov [pFF], FF
    2) Вызываем FF, через pFF:
    Код (Text):
    1. invoke pFF, <параметры>
    По этим пунктам должно быть понятно, почему ваша FF не вызывается напрямую через INVOKE. Для компилятора ваша FF это просто число-константа. А INVOKE берет первым параметром адрес ячейки памяти, где располагается нужная для вызова функция. С другой стороны STDCALL не берет адрес функции из указанной ячейки, а интерпретирует переданный параметр как адрес самой функции.
     
  15. Phantom_84

    Phantom_84 New Member

    Публикаций:
    0
    Регистрация:
    6 июн 2007
    Сообщения:
    820
    dword можно жобавить и в самом макросе, например, вместо кода
    Код (Text):
    1. reverse push param
    можно написать код
    Код (Text):
    1. reverse push dword param
     
  16. diamond

    diamond New Member

    Публикаций:
    0
    Регистрация:
    21 май 2004
    Сообщения:
    507
    Адрес:
    Russia
    Эээ... это чтобы короткий "push 0" (6A 00) превратился в длинный "push dword 0" (68 00 00 00 00)?
     
  17. GoldFinch

    GoldFinch New Member

    Публикаций:
    0
    Регистрация:
    29 мар 2008
    Сообщения:
    1.775
    это чтобы фасм выставлял размер любой переменной в dword, т.к.
    use32 / x dw 0 / push [x] - будет пихать в стек word
     
  18. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    нда проверил - и вправду так... никак не ожидал что в fasm всё нааастолько запущено...
     
  19. GoldFinch

    GoldFinch New Member

    Публикаций:
    0
    Регистрация:
    29 мар 2008
    Сообщения:
    1.775
    Для этого есть push, pushd и pushw. Push не изменяет размер операнда, а pushd и pushw изменяют. Все это написано в справке:
     
  20. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    GoldFinch
    Что это не баг, а документированная фича понятно, но смешивать без крайней необходимости 16 и 32 битный код не есть хороший стиль программирования, а уж особенно применительно к стеку, сильно чуствительному к выравниванию (попробуй, например, перед мессажебоксом временно сохранить ax через pushw, чтобы затем восстановить его ;).
    Поэтому по умолчанию правильно всё таки push/pop делать в соответствии с use16/32, а не в соответствии с размером операнда, а если ооочень нужно word в стеке при use32, то для этого уже pushw использовать.