返回值中的CTypes错误

2024-04-28 04:40:43 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在测试一个非常简单的NASM dll(64位)从ctypes调用。我传递一个int_64,该函数将返回一个不同的int_64。在

我每次都会犯同样的错误:

OSError: exception: access violation writing 0x000000000000092A

其中十六进制值转换为我返回的值(在本例中为2346)。如果我改变这个值,十六进制值就会变成那个值,所以问题出在我用rax返回的值上。如果我指定mov rax,2346,我也会得到同样的错误。在

我反复测试了这个问题,尝试了不同的方法,我做了很多研究,但这个看似简单的问题仍然没有解决。在

下面是Python代码:

^{pr2}$

以下是NASM代码:

[BITS 64]

export lcm

section .data
return_val: dq 2346

section .text
finit

lcm:
push rdi
push rbp
mov rax,qword[return_val]
pop rbp
pop rdi

感谢您提供帮助解决此问题的任何信息。在


Tags: 代码return错误sectionvalpoppushint
1条回答
网友
1楼 · 发布于 2024-04-28 04:40:43

您的函数正确地将23460x92a)加载到RAX中。然后,由于您没有jmpret,所以执行将继续到下面的一些字节。

在这种情况下,我们可以推断出以下字节可能是00 00,它解码为add byte [rax], al,因此access violation writing 0x000000000000092A错误消息。(也就是说,它抱怨的地址是你的固定地址,这不是巧合)。在

正如michaelpetch所说,使用调试器会发现问题所在。在

您也不需要保存/恢复rdi,因为您没有接触它。windowsx86-64调用约定有许多调用清除寄存器,因此对于一个最不常见的多个函数,您不应该需要保存/恢复任何内容,只需使用rax、rcx、rdx、r8、r9和其他Windows允许您删除的内容(我忘了,请查看x86 tag wiki中的调用约定文档,尤其是Agner Fog的指南)。在


一定要在文件顶部使用default rel,这样[return_val]加载将使用RIP相对寻址模式,而不是绝对寻址模式。在


而且,finit永远不会执行,因为它在函数标签之前。在前面的asm问题中,finit是相同的:Passing arrays to NASM DLL, pointer value gets reset to zero,这里也不需要也不执行它。调用约定要求在函数进入(和返回)时,x87 FPU已经处于finit所处的状态。因此,在执行fmulpfidivr之类的x87指令之前不需要它。但无论如何,您并没有这样做,您使用的是SSE-FP指令(这是推荐的,尤其是在64位模式下),它根本不接触x87状态。在

去读一本好的教程和一些文档(x86标签wiki中的一些链接),这样你就可以很好地理解正在发生的事情,这样就可以自己调试这样的问题了,否则你就很难再写更复杂的东西了。猜测什么可能有效对asm不太有效。在

<>从一个被删除的非答案:^ {A3}演示如何设置VisualStudio来构建C++和NASM源的可执行文件,这样就可以调试它。在

相关问题 更多 >