Разница между invoke и call. Как передать адрес строки?

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

  1. alexandersivak

    alexandersivak New Member

    Публикаций:
    0
    Регистрация:
    22 окт 2020
    Сообщения:
    10
    Мне надо разобраться в следующем... Использую IDE RadAsm 2.2.2.3
    Процедуру можно вызвать несколькими способами.
    Например,
    Код (Text):
    1. invoke proc, arg1, arg2
    Или так:
    Код (Text):
    1. push arg1
    2. push arg2
    3. call proc
    В чём разница? Как сделать хорошо?

    Дальше, ради примера... Как передать строку, символ, чтобы добавить этот символ к строке и вернуть эту строку в место вызова для того, чтобы вывести её на экран? Как вообще это делается? Другой пример, надо удалить все пробелы из переменной, которую я получил в процедуре в виде аргумента.
    У меня также стоит masm32 editor. Как основание для любой программы использую следующий код.
    Код (Text):
    1. .386
    2. .model flat, stdcall
    3. option casemap: none
    4. include /masm32/include/windows.inc
    5. include /masm32/include/user32.inc
    6. include /masm32/include/kernel32.inc
    7. includelib /masm32/lib/user32.lib
    8. includelib /masm32/lib/kernel32.lib
    9. .data
    10. msg_title db "Title", 0
    11. msg_message db "Hello world", 0
    12. .code
    13. start:
    14. invoke MessageBox, 0, addr msg_message, addr msg_title, MB_OK
    15. invoke ExitProcess, 0
    16. end start
     
  2. ormoulu

    ormoulu Well-Known Member

    Публикаций:
    0
    Регистрация:
    24 янв 2011
    Сообщения:
    1.208
    Разницы нет: https://docs.microsoft.com/en-us/cpp/assembler/masm/invoke?view=vs-2019

    Уточните, откуда что вам нужно получить и куда вывести. Код в вашем примере - программа под Windows, выводящая окно с сообщением, так называемый Message Box.

    Это просто текстовый редактор. С тем же успехом вы можете использовать notepad.
     
  3. alexandersivak

    alexandersivak New Member

    Публикаций:
    0
    Регистрация:
    22 окт 2020
    Сообщения:
    10
    Надо передать строку и символ. В конце её присоединить его. Когда эта процедура вернётся, вывести строку на экран.
     
  4. _edge

    _edge Well-Known Member

    Публикаций:
    1
    Регистрация:
    29 окт 2004
    Сообщения:
    631
    Адрес:
    Russia
    Я бы использовал для ввода и вывода консоль (программа будет работать в черном окне), чтобы в коде было виднее логику программы / чтобы было проще программировать именно логику, а не обвязку взаимодействия с пользователем. ИМХО.

    В качестве примера - оконная программа с логикой (lab1). Кодес для Fasm, кодес не мой, возможно не компилируемый, но с комментариями.
    Также 2 примера для Masm, консольные, компилируемые.

    Надеюсь, все это окажется полезным.
     

    Вложения:

    • lab1.asm
      Размер файла:
      5,8 КБ
      Просмотров:
      276
    • denis1.asm
      Размер файла:
      745 байт
      Просмотров:
      253
    • denis.asm
      Размер файла:
      959 байт
      Просмотров:
      239
    alexandersivak нравится это.
  5. GRAFik

    GRAFik Active Member

    Публикаций:
    0
    Регистрация:
    14 мар 2020
    Сообщения:
    352
    У меня все скомпилировалось. В хозяйстве пригодится. Спасибо.
     
  6. ormoulu

    ormoulu Well-Known Member

    Публикаций:
    0
    Регистрация:
    24 янв 2011
    Сообщения:
    1.208
    Передать в аргументах процедуры? В командной строке программы? Как консольный ввод? В поле ввода в диалоговом окне? Под какую ОС должна быть программа?
     
  7. f13nd

    f13nd Well-Known Member

    Публикаций:
    0
    Регистрация:
    22 июн 2009
    Сообщения:
    1.953
    invoke это макрос, самостоятельно компонующий аргументы в push'и, call это инструкция. Вот и вся разница. Строки принято передавать процедурам в виде указателей, символ тоже можно не морочиться и оформить как строку, вот так и сделай. Если строка находится в глобальных переменных (имеет фисированный или релоцируемый адрес), тупо передай ее метку (offset <label> в масмосинтаксисе вроде), если в локальных (в стекфрейме), то адрес получается инструкцией lea (в *x-синтаксисе фасма есть удобная директива addr для этого: invoke procedure,addr szStr1,addr szStr2, а как с этим в масме хз).
     
    Последнее редактирование: 23 окт 2020
    alexandersivak нравится это.
  8. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.708
    в масм32 директива addr сама определяет глобальная переменная или локальная, соответственно будет сгенерирована либо lea reg,szStr/push reg либо push offset szStr
     
    f13nd нравится это.
  9. Indy_

    Indy_ Well-Known Member

    Публикаций:
    4
    Регистрация:
    29 апр 2011
    Сообщения:
    4.775
    alexandersivak,

    > В чём разница? Как сделать хорошо?

    Разница в том, что второй код нэйтив, архитектурный асм; первый же макрос - текстовый скрипт. Это используется для уменьшения количества текста.
     
  10. alexandersivak

    alexandersivak New Member

    Публикаций:
    0
    Регистрация:
    22 окт 2020
    Сообщения:
    10
    Код (Text):
    1. lea esi, [var]; взятие адреса, 32-х разрядного в RadAsm
    2. [esi]; разыменование первого символа строки
    Здесь всё правильно понял?
     
  11. Indy_

    Indy_ Well-Known Member

    Публикаций:
    4
    Регистрация:
    29 апр 2011
    Сообщения:
    4.775
    alexandersivak,

    Нет не понял. Потому что ты не понимаешь как устроена адресная трансляция.
     
    alexandersivak нравится это.
  12. alexandersivak

    alexandersivak New Member

    Публикаций:
    0
    Регистрация:
    22 окт 2020
    Сообщения:
    10
    Пока разбираюсь в режимах адресации - режим регистровой косвенной адресации.
    Мой код:
    Код (Text):
    1. sub edx,[esi]
    В дебаггере в
    Код (Text):
    1. edx
    записано значение 00680000, а в
    Код (Text):
    1. esi
    00403125.
    Первое, как будет рассчитан результат? (Я просто вычел - не сошлось с результатом в дебаггере)

    Дополнительный вопрос. В дебаггере мой код выглядит иначе:
    Код (Text):
    1. sub edx,DWORD PTR ds: [esi]
    Зачем здесь
    Код (Text):
    1. DWORD PTR ds
    ?
     
  13. _edge

    _edge Well-Known Member

    Публикаций:
    1
    Регистрация:
    29 окт 2004
    Сообщения:
    631
    Адрес:
    Russia
    Отвечу.
    По Edx и Esi, из Edx вычитается не Esi, а четырехбайтовое (Dword) значение, находящееся по адресу Ds:[Esi]
    Адресация относительно сегмента (селектора) DS: по умолчанию, поэтому в исходом тексте Вам это указывать не нужно, а дебаггер показывает, как оно на самом деле.
     
  14. Indy_

    Indy_ Well-Known Member

    Публикаций:
    4
    Регистрация:
    29 апр 2011
    Сообщения:
    4.775
    alexandersivak,

    IA

    https://software.intel.com/content/...-volumes-1-2a-2b-2c-2d-3a-3b-3c-3d-and-4.html

    Это эффективный адрес который приводится к линейному сложением с базой сегмента.

    3.7.4:

    --- Сообщение объединено, 24 окт 2020 ---
    > Зачем здесь

    --> default segments.
     
    alexandersivak нравится это.