Visual Studio 2005. Линко obj файлов, сделанных ml64.exe.

Тема в разделе "WASM.X64", создана пользователем Span, 5 янв 2009.

  1. Span

    Span New Member

    Публикаций:
    0
    Регистрация:
    5 ноя 2006
    Сообщения:
    134
    Прочитал все топики в этой теме - не нашел ответа. Гугл тоже не помог.

    Пытаюсь вызвать процедуру, написанную на asm из кода CPP в x64 режиме. (до этого все отлично работало через inlinte asm)
    Написал 2 файла:
    1) ml64_test.cpp
    Код (Text):
    1. extern void invoke_me();
    2. int main(int argc, char* argv[])
    3. {
    4.     invoke_me();
    5.     return 0;
    6. }
    2) calc.asm
    Код (Text):
    1. PUBLIC invoke_me
    2. .CODE
    3.  
    4. invoke_me PROC
    5.       mov         rax, rcx
    6.       add         rax, rdx
    7.       ret
    8. invoke_me ENDP
    9. END
    строка для компиляции в файл obj: ml64.exe /c /nologo /Fo $(OutDir)\calc.obj $(InputDir)\$(InputFileName) /W3 /Zi

    Оба файла с кодом добавлены в проект, в соответствующий папках появляются файлы .obj.
    Но когда дело доходит до link.exe - получаю LNK2019: unresolved external symbol "void __cdecl invoke_me(void)" (?invoke_me@@YAXXZ)

    Может кто-нибудь подскажет, в чем проблема?

    приложил сам проект, на всякий случай.

    поправил немного
     
  2. Span

    Span New Member

    Публикаций:
    0
    Регистрация:
    5 ноя 2006
    Сообщения:
    134
    Пока ничего не получилось...
    Будет время - попробую еще.

    Пока удалось сделать через dll: компилирую asm код в бинарник dll, подключаю соответствующую либу к проекту - и работает.

    Но таскать с собой еще один модуль не хочется.
     
  3. TermoSINteZ

    TermoSINteZ Синоби даоса Команда форума

    Публикаций:
    2
    Регистрация:
    11 июн 2004
    Сообщения:
    3.551
    Адрес:
    Russia
    Span
    Во первых ml64 генерит stdcall. Во вторых пропиши объектник в опции Линкера, в проекте.

    А вообще лучше юзать кастом билд тулс. И туда прописать masm64.rules
     
  4. Span

    Span New Member

    Публикаций:
    0
    Регистрация:
    5 ноя 2006
    Сообщения:
    134
    Спасибо.
    Насколько я понял, в x64 существует только один Calling Convention (4 register fast-call calling convention, with stack-backing for those registers).


    Дык я так и сделал. В опциях asm файла, в единственном шаге (Custom Build Step) прописал строку для компиляции в obj через ml64.

    Не знаю в чем причина, но после перезапуска студии и утреннего переосмысления задачи все заработало без изменения кода...

    Возможно, этот вопрос еще у кого-нибудь возникнет, так что приложил проект, на всякий случай.
     
  5. Ustus

    Ustus New Member

    Публикаций:
    0
    Регистрация:
    8 авг 2005
    Сообщения:
    834
    Адрес:
    Харьков
    Ну так вот дело именно в этом. Цепепе искажает имена и требует соответственно искаженных. Поэтому или в ASM-исходнике такое имя и использовать, или в ASM объявлять _invoke_me, а в CPP - соответственно extern "C" void invoke_me();
     
  6. Span

    Span New Member

    Публикаций:
    0
    Регистрация:
    5 ноя 2006
    Сообщения:
    134
    Разобрался

    Еще вопрос почти по теме:

    Почему Visual Studio 2005 по разному передает параметры в ф-ю при включенном или выключенном параметра O2 (Maximum Speed)?

    У меня просто перестают передаваться параметры в ф-ю...
     
  7. Span

    Span New Member

    Публикаций:
    0
    Регистрация:
    5 ноя 2006
    Сообщения:
    134
    Правильно человек в соседней ветке советовал почитать ABI.

    В одной процедуре использовал Nonvolatile регистры и не восстанавливал при выходе.
    Оказалось, если компилировать без /O2 - все Ок, компилятор генерирует код, который "прощает" это.

    В противном случае данные из этих регистров использовались и вне моей процедуры. Отсюда и были ошибки.

    Сразу не понял, т.к. отладку осложняется при компиляции с /О2:
    не могу поставить в студии бряк на строчку кода ((( Пришлось вставлять int 3 руками в коде на асме.

    Странно что с этим ключом отладчик не реагирует на бряки.