【问题标题】: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 中。 然后执行继续到后面的一些字节,因为你没有jmpret

在这种情况下,我们可以推断以下字节可能是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 问题中,您有相同的 finitPassing arrays to NASM DLL, pointer value gets reset to zero,它也不需要也没有执行。调用约定要求在函数进入(和返回)时,x87 FPU 或多或少已经处于finit 放入的状态。因此在执行 x87 指令(如 fmulpfidivr)之前不需要它。但无论如何你并没有这样做,你使用的是 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
    相关资源
    最近更新 更多