我正在测试一个非常简单的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
感谢您提供帮助解决此问题的任何信息。在
您的函数正确地将
2346
(0x92a
)加载到RAX中。然后,由于您没有jmp
或ret
,所以执行将继续到下面的一些字节。在这种情况下,我们可以推断出以下字节可能是
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
所处的状态。因此,在执行fmulp
和fidivr
之类的x87指令之前不需要它。但无论如何,您并没有这样做,您使用的是SSE-FP指令(这是推荐的,尤其是在64位模式下),它根本不接触x87状态。在去读一本好的教程和一些文档(x86标签wiki中的一些链接),这样你就可以很好地理解正在发生的事情,这样就可以自己调试这样的问题了,否则你就很难再写更复杂的东西了。猜测什么可能有效对asm不太有效。在
<>从一个被删除的非答案:^ {A3}演示如何设置VisualStudio来构建C++和NASM源的可执行文件,这样就可以调试它。在相关问题 更多 >
编程相关推荐