Недавно начал создавать dll на масме64 для си++. Почитал на http://msdn.microsoft.com/ru-ru/library/ms235286.aspx соглашение о вызовах в x64, и оказывается, соглашение только одно - fastcall. Написал вот такой код: Код (Text): option casemap:none .code dllMain proc hinstDLL:qword, fdwReason:dword, lpvReserved:qword mov rax,1 ret dllMain endp memCpy64 proc a:qword, b:qword, c:qword, d:qword, e:qword mov rax,a mov rbx,b ret memCpy64 endp end , запустил Visual Studio с программой, использующей эту dll. И вот что обнаружил: 1. mov rax,a почему-то берёт "а" из стека, а не из регистра rcx, естественно, в rax загружается мусор. 2. ret не освобождает стек, а при соглашении fastcall стек должна освобождать вызываемая подпрограмма. Ну с параметрами всё просто, я могу написать mov rax,rcx, а вот со стеком у меня возник вопрос: "Должен ли я вручную освобождать стек, т. е. писать ret XX?" Но, может быть чтобы вышеописанных ошибок не происходило, я должен что-то дописать, например "proc fastcall" или ещё что-то?
В смысле правильно? 1. По идее а нужно брать из регистра а процедура берёт из стека, разве правильно? 2. Разве правильно, что стек не освобождается?
1. a передаётся в rcx но место в стэке под неё все равно зарезервировано. 2. Правильно. Функции условно деляться на два типа ветви (вызывают WINAPI функции) и листья (не вызывают WINAPI функции). С ml64 по нормальному можно писать только листья. Для написания ветвей уже нужны макросы.
Но тогда получается, что в x64 используется не соглашение в вызовах fastcall, а что-то среднее между fastcall(парамерты через регистры) cdecl(стек очищает вызывающая программа). А в msdn написано, что fastcall. В msdn ошибка?
Просто решили так назвать. Описание там исчерпывающее и при правильном понимании путаницы не должно быть.