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

Discussion in 'WASM.BEGINNERS' started by alexandersivak, Oct 22, 2020.

  1. alexandersivak

    alexandersivak New Member

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

    Дальше, ради примера... Как передать строку, символ, чтобы добавить этот символ к строке и вернуть эту строку в место вызова для того, чтобы вывести её на экран? Как вообще это делается? Другой пример, надо удалить все пробелы из переменной, которую я получил в процедуре в виде аргумента.
    У меня также стоит masm32 editor. Как основание для любой программы использую следующий код.
    Code (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

    Blog Posts:
    0
    Joined:
    Jan 24, 2011
    Messages:
    1,206
    Разницы нет: https://docs.microsoft.com/en-us/cpp/assembler/masm/invoke?view=vs-2019

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

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

    alexandersivak New Member

    Blog Posts:
    0
    Joined:
    Oct 22, 2020
    Messages:
    10
    Надо передать строку и символ. В конце её присоединить его. Когда эта процедура вернётся, вывести строку на экран.
     
  4. _edge

    _edge Well-Known Member

    Blog Posts:
    1
    Joined:
    Oct 29, 2004
    Messages:
    631
    Location:
    Russia
    Я бы использовал для ввода и вывода консоль (программа будет работать в черном окне), чтобы в коде было виднее логику программы / чтобы было проще программировать именно логику, а не обвязку взаимодействия с пользователем. ИМХО.

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

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

    Attached Files:

    alexandersivak likes this.
  5. GRAFik

    GRAFik Active Member

    Blog Posts:
    0
    Joined:
    Mar 14, 2020
    Messages:
    350
    У меня все скомпилировалось. В хозяйстве пригодится. Спасибо.
     
  6. ormoulu

    ormoulu Well-Known Member

    Blog Posts:
    0
    Joined:
    Jan 24, 2011
    Messages:
    1,206
    Передать в аргументах процедуры? В командной строке программы? Как консольный ввод? В поле ввода в диалоговом окне? Под какую ОС должна быть программа?
     
  7. f13nd

    f13nd Well-Known Member

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

    Mikl___ Супермодератор Staff Member

    Blog Posts:
    14
    Joined:
    Jun 25, 2008
    Messages:
    3,925
    в масм32 директива addr сама определяет глобальная переменная или локальная, соответственно будет сгенерирована либо lea reg,szStr/push reg либо push offset szStr
     
    f13nd likes this.
  9. Indy_

    Indy_ Well-Known Member

    Blog Posts:
    4
    Joined:
    Apr 29, 2011
    Messages:
    4,789
    alexandersivak,

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

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

    alexandersivak New Member

    Blog Posts:
    0
    Joined:
    Oct 22, 2020
    Messages:
    10
    Code (Text):
    1. lea esi, [var]; взятие адреса, 32-х разрядного в RadAsm
    2. [esi]; разыменование первого символа строки
    Здесь всё правильно понял?
     
  11. Indy_

    Indy_ Well-Known Member

    Blog Posts:
    4
    Joined:
    Apr 29, 2011
    Messages:
    4,789
    alexandersivak,

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

    alexandersivak New Member

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

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

    _edge Well-Known Member

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

    Indy_ Well-Known Member

    Blog Posts:
    4
    Joined:
    Apr 29, 2011
    Messages:
    4,789
    alexandersivak,

    IA

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

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

    3.7.4:

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

    --> default segments.
     
    alexandersivak likes this.