Ругань fasm'a

Discussion in 'WASM.BEGINNERS' started by zukalo, Oct 22, 2008.

  1. zukalo

    zukalo New Member

    Blog Posts:
    0
    Joined:
    Oct 22, 2008
    Messages:
    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

    Blog Posts:
    0
    Joined:
    Sep 29, 2005
    Messages:
    2,566
    zukalo
    Вам стоит научиться различать stdcall и invoke.
     
  3. zukalo

    zukalo New Member

    Blog Posts:
    0
    Joined:
    Oct 22, 2008
    Messages:
    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

    Blog Posts:
    0
    Joined:
    Jan 15, 2007
    Messages:
    1,494
    потому что получается
    invoke FF, [dta].....
    меняется на
    stdcall [FF], [dta].......
    Вот и подумайте как это относится.
     
  5. zukalo

    zukalo New Member

    Blog Posts:
    0
    Joined:
    Oct 22, 2008
    Messages:
    20
    Заставил работать через Stdcall так:
    stdcall dword FF, ...

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

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

    dead_body wasm.ru

    Blog Posts:
    0
    Joined:
    Sep 3, 2004
    Messages:
    603
    Location:
    Украина;г.Харьков;г.Н.Каховка
    zukalo
    invoke - для вызова функций
    stdcall - для вызова процедур

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

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

    l_inc New Member

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

    zukalo New Member

    Blog Posts:
    0
    Joined:
    Oct 22, 2008
    Messages:
    20
    Всем спасибо за отзывы.

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

    _basmp_ New Member

    Blog Posts:
    0
    Joined:
    Jul 10, 2005
    Messages:
    2,939
    зачем вообще эти инвоке и стдкалл? Почему не писать все через калл? Прога станет интереснее и вопросов таких не будет.
     
  10. GoldFinch

    GoldFinch New Member

    Blog Posts:
    0
    Joined:
    Mar 29, 2008
    Messages:
    1,775
    а еще лучше написать свои инвок и стдколл, в которых ты будеш 100% разбираться
     
  11. zukalo

    zukalo New Member

    Blog Posts:
    0
    Joined:
    Oct 22, 2008
    Messages:
    20
    Дак через invoke быстрее, удобнее да и принято как-то)
     
  12. GoldFinch

    GoldFinch New Member

    Blog Posts:
    0
    Joined:
    Mar 29, 2008
    Messages:
    1,775
    осталось только узнать как он работает =\
     
  13. l_inc

    l_inc New Member

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

    Osen Рие

    Blog Posts:
    0
    Joined:
    Apr 5, 2008
    Messages:
    283
    Location:
    Париж
    zukalo
    Если уж вам очень хочется вызывать вашу процедуру через INVOKE, то сделайте следующее.

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

    Phantom_84 New Member

    Blog Posts:
    0
    Joined:
    Jun 6, 2007
    Messages:
    820
    dword можно жобавить и в самом макросе, например, вместо кода
    Code (Text):
    1. reverse push param
    можно написать код
    Code (Text):
    1. reverse push dword param
     
  16. diamond

    diamond New Member

    Blog Posts:
    0
    Joined:
    May 21, 2004
    Messages:
    507
    Location:
    Russia
    Эээ... это чтобы короткий "push 0" (6A 00) превратился в длинный "push dword 0" (68 00 00 00 00)?
     
  17. GoldFinch

    GoldFinch New Member

    Blog Posts:
    0
    Joined:
    Mar 29, 2008
    Messages:
    1,775
    это чтобы фасм выставлял размер любой переменной в dword, т.к.
    use32 / x dw 0 / push [x] - будет пихать в стек word
     
  18. Y_Mur

    Y_Mur Active Member

    Blog Posts:
    0
    Joined:
    Sep 6, 2006
    Messages:
    2,494
    нда проверил - и вправду так... никак не ожидал что в fasm всё нааастолько запущено...
     
  19. GoldFinch

    GoldFinch New Member

    Blog Posts:
    0
    Joined:
    Mar 29, 2008
    Messages:
    1,775
    Для этого есть push, pushd и pushw. Push не изменяет размер операнда, а pushd и pushw изменяют. Все это написано в справке:
     
  20. Y_Mur

    Y_Mur Active Member

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