【问题标题】:CTypes error in return value返回值中的 CTypes 错误
【发布时间】:2018-01-27 23:22:55
【问题描述】:

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

我每次都得到同样的错误:

OSError: exception: access violation writing 0x000000000000092A

十六进制值转换为我返回的值(在本例中为 2346)。如果我更改该值,十六进制值将更改为该值,因此问题在于我在 rax 中返回的值。如果我分配 mov rax,2346,我会得到同样的错误。

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

这是 Python 代码:

def lcm_ctypes():

    input_value = ctypes.c_int64(235)

     hDLL = ctypes.WinDLL(r"C:/NASM_Test_Projects/While_Loop_01/While_loops-01.dll")

    CallTest = hDLL.lcm
    CallTest.argtypes = [ctypes.c_int64]
    CallTest.restype = ctypes.c_int64

    retvar = CallTest (input_value)

这是 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

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

【问题讨论】:

  • 可能是因为你的函数丢失了ret?
  • 顺便说一句 finit 什么都不做。它在函数之外,并且您没有使用 x87 FPU 相关指令。它可以被消除。
  • 我还建议您找到有关调试 python 和 DLL 的教程。有许多使用 Visual Studio 的此类教程(即使是免费版本也足够了)。您可以在函数入口点设置断点并让它停在那里。这使您可以逐步查看说明以了解失败的原因。
  • 我建议在尝试使其与 ctypes 一起使用之前,通过从 C 调用该函数来使其工作。问题不是ctypes 问题。

标签: python assembly dll nasm x86-64


【解决方案1】:

您的函数正确地将 2346 (0x92a) 加载到 RAX 中。 然后执行继续到后面的一些字节,因为你没有jmp 或ret。

在这种情况下,我们可以推断以下字节可能是00 00,解码为add byte [rax], al,因此出现access violation writing 0x000000000000092A错误消息。 (即它所抱怨的地址是您的常数并非巧合)。

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

您也不需要保存/恢复rdi,因为您没有触摸它。 Windows x86-64 调用约定有许多 call-clobbered 寄存器,因此对于最不常用的多个函数,您不需要保存/恢复任何内容,只需使用 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 放入的状态。因此在执行 x87 指令(如 fmulp 和 fidivr)之前不需要它。但无论如何你并没有这样做,你使用的是 SSE FP 指令(推荐,尤其是在 64 位模式下),它根本不会触及 x87 状态。

去阅读一个很好的教程和一些文档(x86 标签 wiki 中的一些链接),这样你就可以很好地了解正在发生的事情,以便自己调试这样的问题,否则你将很难写出更复杂的东西。对于 asm 来说,猜测可能会起作用的方法并不是很好。

来自已删除的未回答:https://www.cs.uaf.edu/2017/fall/cs301/reference/nasm_vs/ 展示了如何设置 Visual Studio 以使用 C++ 和 NASM 源构建可执行文件,以便您对其进行调试。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多