【问题标题】:Why does this code cause an access violation exception?为什么这段代码会导致访问冲突异常?
【发布时间】:2010-10-13 11:57:18
【问题描述】:
_memcpy_r SEGMENT

memcpy_r PROC
 mov r10, rdi
 mov r11, rsi
 mov rdi, rcx
 mov rsi, rdx
 mov rcx, r8
 shr rcx, 3
 rep movsq
 mov rcx, r8
 and rcx, 7
 rep movsb
 mov rsi, r11
 mov rdi, r10
 ret
memcpy_r ENDP

_memcpy_r ENDS

END

我在 Visual Studio 2010 项目中使用的 .asm 文件中有上述代码。它设置为使用 Microsoft 宏汇编程序 (ml64.exe) 进行编译。 程序崩溃并在过程的第一行 (mov r10, rdi) 出现访问冲突异常。有谁知道为什么?

编辑:我应该澄清一下。如果我删除第一行,下一行仍然会发生异常。如果我删除它,它会发生在下一个 (mov rdi, rcx)。

【问题讨论】:

  • r10 寄存器是否存在于 x86-64 平台上?我真的在问......从来没有见过这个......您是否尝试过将r10的所有引用更改为rax
  • 我原来有 push rdi,但我仍然得到了异常。另外,如果 r10 不存在,它将无法编译。
  • 是的,如果 src 或 dst 无效,或者 count 为负数或太大,memcopy() 可能会崩溃。
  • 我确定 src 和 dst 是有效的,并且计数是正数。更重要的是,错误发生在第一行,我所做的只是保留 rdi(在我对任何参数做任何事情之前)。

标签: assembly x86 64-bit x86-64


【解决方案1】:

按照 Zack 的建议,尝试将您的过程放在一个包含代码的段中。在 MASM 中,您通常会这样做:

.code
memcpy_r PROC
[ ... ]
memcpy_r ENDP

END

[Edit2] 要与其他代码链接,您可能还需要将PROC 标记为PUBLIC

[编辑1] 附带说明一下,由于您没有另外指定,并且 MASM 是 Windows 程序,我假设您正在组装它以在 Win64 上使用?如果是这种情况,您似乎没有关注Win64 calling convention,它传递了RCXRDXR8R9 中的前4 个参数。

【讨论】:

  • mov r10, rdi mov r11, rsi 以上只是我使用寄存器而不是堆栈来保存 rdi 和 rsi 的值。我在下一行访问我的参数,如您所见,使用 rcx、rdx 和 r8。 .CODE 做到了,谢谢! :)
【解决方案2】:

我怀疑你的问题是你正在为这段代码定义你自己的特殊段,并且它没有在,嗯,可执行文件中被标记为可执行,所以它被加载到执行权限被拒绝的内存区域中。毫无疑问,有一些方法可以告诉 MASM 段将包含代码,而不是数据;试试看。

【讨论】:

    【解决方案3】:

    如果您将项目编译为 i386 可执行文件,那么它将在 Legacy 模式下运行,而无需访问 64 位寄存器(%rax、%r10 等)。也许这就是问题所在?反汇编您的可执行文件并检查编译器生成的代码——i386 或 x86_64。

    【讨论】:

    • 不是这样的。 OP 使用的是 64 位版本的 MASM (ml64.exe),它生成 64 位可执行文件。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多