擅长:python、mysql、java
<p>@Mark Tolonen,非常感谢您的详细分析。我将此作为答案发布,因为代码的格式在注释中无法正确显示,但我选择了您的答案作为最佳答案。在</p>
<p>我怀疑堆栈对齐可能是问题所在,并且您消除了ctypes作为源代码,所以我将重点放在堆栈上。这是我所做的。在</p>
<p>在NASM代码中,我在进入时按rbp和rdi,然后在退出时恢复它们。在这里,在调用之前,我通过从堆栈中弹出rbp和rdi来设置堆栈状态。然后从rsp中减去32个字节(不是40个)。调用完成后,我将恢复堆栈状态:</p>
<pre><code>pop rbp
pop rdi
sub rsp,32
call [CB_Pointer] ; The call to the callback function
add rsp,32
push rdi
push rbp
</code></pre>
<p>对于一个外部函数调用(比如C库函数),我必须减去40个字节,但是对于这个回调,我只需要32个字节。在你回答之前,我试过用40个字节,但没用。我想原因是因为它不是调用外部库,而是对首先调用dll的ctypes代码的回调。在</p>
<p>还有一件事。调用发送一个浮点值(xmm0)并返回一个整数值,但是整数值返回到xmm0寄存器中,而不是rax。将ctypes中的原型设置为整数返回值并不能做到这一点。它必须保持这样:</p>
^{pr2}$
<p>再次感谢你的答复。你带我去哪里找。在</p>
<p>p.S.length_array_out将输入数组的长度传递给NASM。如果我传递了多个数组,则长度_array_out将更长,每个长度有一个qword;目前我在输入时将qword转换为整数。在</p>