Пишу такую программу: Код (Text): format PE64 GUI 4.0 DLL include 'WIN64A.INC' ... mov rax, [m_pDataObj] comcall rax, IDataObject, GetData, etc, stg ... interface IDataObject,\ QueryInterface,\ AddRef,\ Release,\ GetData,\ GetDataHere,\ QueryGetData,\ GetCanonicalFormatEtc,\ SetData,\ EnumFormatEtc,\ DAdvise,\ DUnadvise,\ EnumDAdvise При компиляции для win32 - всё нормально и всё работает как надо: Код (Text): push offset stg push offset etc push eax mov eax, [eax] call dword ptr [eax+0Ch] А при компиляции для win64 - получается такой код: Код (Text): sub rsp, 20h mov rcx, rax mov rdx, offset etc mov r8, offset stg push rax mov rax, [rax] call qword ptr [rax+18h] add rsp, 20h и программа через некоторое время падает из-за нарушения RSP. Если я не использую макрос cominvk, и вручную пишу аналог но без push rax - то всё работает! Почему так ?! Дизассемблировал WIN64\USECOM.EXE - там тоже cominvk с push (но имхо проблемы c RSP нет потому что затем leave). Посмотрел в FASM\INCLUDE\MACRO\COM64.inc - там явно не по ошибке push, там какое-то условие что если handle eqtype rax | handle eqtype 0 то поставить push, а иначе - нормальный fastcall. Однако использование rbx вместо rax - проблему не решает, макрос пишет push rbx... как надо использовать этот cominvk чтобы он не писал в стек ничего ?
f2065 Код (Text): mov rax, [m_pDataObj] comcall rax, IDataObject, GetData, etc, stg В общем-то Вы везде пишете, что используете cominvk, что не очень-то согласуется с этим кодом. Если бы Вы использовали вместо этого кода вызов cominvk m_pDataObj, GetData, etc, stg, было бы всё в порядке. rax в условии никак не связан с rax. В условии может стоять любой регистр. Само условие проверяет, является ли переданный указатель на объект регистром, прямым адресом или адресным выражением. В последнем случае (например, если это локальная переменная вида [rbp-20h]) его нельзя просто так запихать в скобки и таким образом разыменовать. Поэтому это условие является некоторой оптимизацией: получить указатель на методы в одну или, если не получается, то в две инструкции. Что же до push rax, Вы правы. Он там лишний, и это — ошибка.