Я звоню в 64-битную DLL NASM из ctypes.DLL принимает пять входных параметров.В соглашении о вызовах Windows первые четыре передаются в rcx, rdx, r8 и r9, а пятый передается в стеке.
Обзор соглашений о вызовах x64 doc (https://docs.microsoft.com/en-us/cpp/build/overview-of-x64-calling-conventions) говорит: «Любые параметры, кроме первых четырех, должны храниться в стеке, над хранилищем теней для первых четырех, до вызова».Таким образом, поэтому к значению нельзя получить доступ с помощью pop, и я думаю, что к нему следует обращаться с помощью RSP. Если пятые (и более поздние) параметры находятся выше хранилища теней, то я предположил, что это будет RSP минус 40 (mov rax,[rsp-40]), но это не так.
Я попытался «пройтись по стеку», что означает, что я пробовал в rsp-0, rsp-8, rsp-16 и т. д. вплоть до rsp-56, но он не вернул значение, которое я передал в качестве пятого параметра (одиночный 64-битный двойной).
Согласно https://docs.microsoft.com/en-us/cpp/build/stack-allocation, макет стека на входе - это адрес возврата, rcx,rdx, r8, r9 и область параметров стека, так что я ожидаю найти свое значение в rsp-48, но его нет и нет в rsp-56.
Итак, мой вопрос: какполучить доступ к параметру, передаваемому в стеке при входе в dll в Windows, вызывая convention?
РЕДАКТИРОВАТЬ: Вот соответствующий код ctypes:
hDLL = ctypes.WinDLL("C:/Test_Projects/MultiCompare/py_descent.dll")
CallName = hDLL.Main_Entry_fn
CallName.argtypes = [ctypes.POINTER(ctypes.c_double),ctypes.POINTER (ctypes.c_double),ctypes.c_double,ctypes.POINTER(ctypes.c_double),ctypes.c_double]
CallName.restype = ctypes.c_double
ret_ptr = CallName(CA_x,CA_d,CA_mu,length_array_out,CA_N_epochs)
Data types:
CA_x: pointer to double(float) array
CA_d: pointer to double(float) array
CA_mu: double
length_array_out: pointer to double(float) array
CA_N_epochs: double
Вот точка входа в DLL, где получены переменные.Я всегда нажимаю rdi и rbp при входе, поэтому сначала беру параметры, переданные в стек, прежде чем сделать это, чтобы предотвратить смещение стека:
Main_Entry_fn:
; First the stack parameters
movsd xmm0,[rsp+40]
movsd [N_epochs],xmm0
; End stack section
push rdi
push rbp
mov [x_ptr],rcx
mov [d_ptr],rdx
movsd [mu],xmm2
mov [data_master_ptr],r9
; Now assign lengths
; (this part intentionally omitted for brevity)
call py_descent_fn
exit_label_for_Main_Entry_fn:
pop rbp
pop rdi
ret