问题描述
我正在将三个双打数组从Python(3.6.2)传递到使用CTypes用64位NASM(Windows)编写的DLL中.指向数组的指针位于rcx,rdx,r8和r9中.
I am passing three arrays of doubles from Python (3.6.2) into a DLL written in 64-bit NASM (Windows) using CTypes. The pointers to the arrays are in rcx, rdx, r8 and r9.
在进入时,我将指针提取到三个单独的数组中,称为a_in_data,b_in_data和c_in_data.这些数组的元素是(1)指针(2)数据类型和(3)长度.
On entry, I extract the pointers into three separate arrays, called a_in_data,b_in_data, and c_in_data. The elements of those arrays are (1) pointer (2) data type and (3) length.
在下面的代码中"Test#1"开头的区域中,我们检查b_in_data [0]处的值,并获得一个有效的指针(只需删除注释符号并跳到最后).
In the area preceded by "Test #1" in the code below we check the value at b_in_data[0] and we get a valid pointer (just remove the comment symbols and jump to the end).
在"Test#2"之前的区域中,我们检查b_in_data [0]处的值,并且得到零.此时,数组b_in_data [0]尚未更改,但是以某种方式将其设置为零.
In the area preceded by "Test #2" we check the value at b_in_data[0] and we get zero. The array b_in_data[0] has not been changed by this point, but somehow it gets set to back zero.
在c_in_data之后的块中也发生了同样的情况.由于某些原因,第一个代码块(以提取数据类型和长度"为标题)将b_in_data和c_in_data中的第一个值清零.
The same happens in the block following for c_in_data. For some reason, the first code block (headed by "Extract data type and length") zeroes out the first value in b_in_data and c_in_data.
我已经确定了引起问题的那条线;它后面带有注释此行是问题,但不清楚为什么".
I have identified the line that is causing the problem; it's followed by the comment "THIS LINE IS THE PROBLEM, BUT IT'S NOT CLEAR WHY."
Python代码很长,但是如果它有助于重现此代码,请询问,我将其发布.这是NASM代码:
The Python code is long, but if it helps to reproduce this, please ask and I will post it. Here is the NASM code:
; Header Section
[BITS 64]
export TryThemAll
section .data
a_in_data: dd 0, 0, 0
b_in_data: dd 0, 0, 0
c_in_data: dd 0, 0, 0
out_array_pointer: dd 0
call_var_length: dd 0
section .text
finit
; _________________
TryThemAll:
push rdi
push rbp
push qword rcx
pop qword [a_in_data]
push qword rdx
pop qword [b_in_data]
push qword r8
pop qword [c_in_data]
push qword r9
pop qword [out_array_pointer]
; Test #1
; Now the value at b_in_data[0] is the pointer we just extracted from rdx
;mov rbp,b_in_data
;mov rax,qword [rbp]
;jmp out_here
;_______
; Extract data type and length
mov rdi,[out_array_pointer]
mov rbp,a_in_data
movsd xmm0,qword [rdi] ;Data type for a_in
cvttsd2si rax,xmm0
mov [rbp+8],rax ; THIS LINE IS THE PROBLEM, BUT IT'S NOT CLEAR WHY
movsd xmm0,qword [rdi+8] ;Length for a_in
cvttsd2si rax,xmm0
mov [rbp+16],rax
mov rbp,b_in_data
movsd xmm0,qword [rdi+16] ;Data type for b_in
cvttsd2si rax,xmm0
mov [rbp+8],rax
movsd xmm0,qword [rdi+24] ;Length for b_in
cvttsd2si rax,xmm0
mov [rbp+16],rax
; Test #2
; Now the value at [0] in b_in_data is zero !!!
mov rbp,b_in_data
mov rax,qword [rbp]
jmp out_here
mov rbp,c_in_data
movsd xmm0,qword [rdi+32] ;Data type for c_in
cvttsd2si rax,xmm0
mov [rbp+8],rax
movsd xmm0,qword [rdi+40] ;Length for c_in
cvttsd2si rax,xmm0
mov [rbp+16],rax
;_______
out_here:
pop rbp
pop rdi
ret
在此先感谢您的帮助.
Thanks in advance for any help.
推荐答案
此问题的解决方案非常简单.在.data节中,三个数组a_in_data,b_in_data和c_in_data连续定义为"dd",但应定义为"dq"以每个元素占用八个字节,而不是四个字节.自然地,连续的写操作会过多存储相邻的值.
The solution to this problem was quite simple. The three arrays a_in_data, b_in_data and c_in_data were defined contiguously in the .data section as "dd" but should have been defined as "dq" to occupy eight bytes per element instead of four. Naturally successive writes had the effect of overstoring adjacent values.
我最近从32位MASM切换到了64位NASM,但我仍然习惯于NASM语法和64位汇编程序设计,因此我仍然犯了一些基本的错误.
I recently switched from 32-bit MASM to 64-bit NASM and I'm still getting used to NASM syntax and 64-bit assembly programming, so I'm still making some elementary mistakes.
谢谢你,彼得,我花了很多时间.您还提出了其他一些有趣的观点.例如,我改用lea(加载有效地址),而不是将指针移动到rbp(例如mov rbp,b_in_data).
Thanks, Peter, for the time you took on this. You made some other interesting points. For example, I've switched to using lea (load effective address) instead of moving the pointer to rbp (e.g., mov rbp,b_in_data).
再次感谢,感谢Michael Petch添加了其他标签.
Thanks again, and thanks to Michael Petch for adding the other tags.
顺便说一句,这些数据都被转换为64位整数,因此不需要struc,它们不是混合类型.
BTW, these data are all converted to 64-bit integers, so the struc is not necessary -- they are not mixed types.
这篇关于将数组传递给NASM DLL,指针值重置为零的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!