Прочитал все топики в этой теме - не нашел ответа. Гугл тоже не помог. Пытаюсь вызвать процедуру, написанную на asm из кода CPP в x64 режиме. (до этого все отлично работало через inlinte asm) Написал 2 файла: 1) ml64_test.cpp Код (Text): extern void invoke_me(); int main(int argc, char* argv[]) { invoke_me(); return 0; } 2) calc.asm Код (Text): PUBLIC invoke_me .CODE invoke_me PROC mov rax, rcx add rax, rdx ret invoke_me ENDP 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) Может кто-нибудь подскажет, в чем проблема? приложил сам проект, на всякий случай. поправил немного
Пока ничего не получилось... Будет время - попробую еще. Пока удалось сделать через dll: компилирую asm код в бинарник dll, подключаю соответствующую либу к проекту - и работает. Но таскать с собой еще один модуль не хочется.
Span Во первых ml64 генерит stdcall. Во вторых пропиши объектник в опции Линкера, в проекте. А вообще лучше юзать кастом билд тулс. И туда прописать masm64.rules
Спасибо. Насколько я понял, в x64 существует только один Calling Convention (4 register fast-call calling convention, with stack-backing for those registers). Дык я так и сделал. В опциях asm файла, в единственном шаге (Custom Build Step) прописал строку для компиляции в obj через ml64. Не знаю в чем причина, но после перезапуска студии и утреннего переосмысления задачи все заработало без изменения кода... Возможно, этот вопрос еще у кого-нибудь возникнет, так что приложил проект, на всякий случай.
Ну так вот дело именно в этом. Цепепе искажает имена и требует соответственно искаженных. Поэтому или в ASM-исходнике такое имя и использовать, или в ASM объявлять _invoke_me, а в CPP - соответственно extern "C" void invoke_me();
Разобрался Еще вопрос почти по теме: Почему Visual Studio 2005 по разному передает параметры в ф-ю при включенном или выключенном параметра O2 (Maximum Speed)? У меня просто перестают передаваться параметры в ф-ю...
Правильно человек в соседней ветке советовал почитать ABI. В одной процедуре использовал Nonvolatile регистры и не восстанавливал при выходе. Оказалось, если компилировать без /O2 - все Ок, компилятор генерирует код, который "прощает" это. В противном случае данные из этих регистров использовались и вне моей процедуры. Отсюда и были ошибки. Сразу не понял, т.к. отладку осложняется при компиляции с /О2: не могу поставить в студии бряк на строчку кода ((( Пришлось вставлять int 3 руками в коде на асме. Странно что с этим ключом отладчик не реагирует на бряки.