【问题标题】:Porting Inline GASM to x64 MASM Access Violation Issue将内联 GASM 移植到 x64 MASM 访问冲突问题
【发布时间】:2013-12-01 03:43:54
【问题描述】:

我目前正在将一些代码从为 GCC Linux 编写的 https://github.com/mono 项目移植到 MS Windows x64,我遇到了一些挑战。

目前我不确定我从 x64 AT&T 内联 ASM 到 x64 MASM 的翻译是否正确。它编译得很好,但我的测试用例失败了,因为我的 ASM 函数执行后memcpy 抛出异常/内存访问冲突。 我的翻译正确吗?

我真正受到挑战的一件事是rip 在 Windows x64 MASM 中无法访问?我真的不知道如何翻译 AT&T 语法的剩余行(见下文)。但我给了它最好的尝试。 我是否正确处理了缺少rip 访问权限的问题?

如果我的工作正确,那么为什么 memcpy 会失败?

这里是相关的C++:

void mono_context_get_current(MonoContext cnt); //declare the ASM func

//Pass the static struct pointer to the ASM function mono_context_get_current
//The purpose here is to clobber it
#ifdef _MSC_VER
#define MONO_CONTEXT_GET_CURRENT(ctx) do { \
    mono_context_get_current(ctx);  \
    } while (0)
#endif

static MonoContext cur_thread_ctx = {0};

MONO_CONTEXT_GET_CURRENT (cur_thread_ctx);
memcpy (&info->ctx, &cur_thread_ctx, sizeof (MonoContext)); //memcpy throws Exception.

这是当前的 ASM 函数。

mono_context_get_current PROTO
.code
mono_context_get_current PROC
mov rax, rcx ;Assume that rcx contains the pointer being passed
mov [rax+00h], rax
mov [rax+08h], rbx
mov [rax+10h], rcx
mov [rax+18h], rdx ;purpose is to offset from my understanding of the GCC assembly
mov [rax+20h], rbp
mov [rax+28h], rsp
mov [rax+30h], rsi
mov [rax+38h], rdi
mov [rax+40h], r8
mov [rax+48h], r9
mov [rax+50h], r10
mov [rax+58h], r11
mov [rax+60h], r12
mov [rax+68h], r13
mov [rax+70h], r14
mov [rax+78h], r15
call $ + 5
mov rdx, [rax+80h]
pop rdx
mono_context_get_current ENDP
END

据我了解,rcx 寄存器应该包含结构指针,并且我应该使用rdxpop

正如我所提到的,我有适用于非 Win64 平台的 GCC ASM,它似乎可以在这些平台上运行。这段代码是这样的:

#define MONO_CONTEXT_GET_CURRENT(ctx)        \
        __asm__ __volatile__(        \
                "movq $0x0, 0x00(%0)\n"        \
                "movq %%rbx, 0x08(%0)\n"        \
                "movq %%rcx, 0x10(%0)\n"        \
                "movq %%rdx, 0x18(%0)\n"        \
                "movq %%rbp, 0x20(%0)\n"        \
                "movq %%rsp, 0x28(%0)\n"        \
                "movq %%rsi, 0x30(%0)\n"        \
                "movq %%rdi, 0x38(%0)\n"        \
                "movq %%r8, 0x40(%0)\n"        \
                "movq %%r9, 0x48(%0)\n"        \
                "movq %%r10, 0x50(%0)\n"        \
                "movq %%r11, 0x58(%0)\n"        \
                "movq %%r12, 0x60(%0)\n"        \
                "movq %%r13, 0x68(%0)\n"        \
                "movq %%r14, 0x70(%0)\n"        \
                "movq %%r15, 0x78(%0)\n"        \
                "leaq (%%rip), %%rdx\n"        \
                "movq %%rdx, 0x80(%0)\n"        \
                :         \
                : "a" (&(ctx))        \
                : "rdx", "memory")

感谢您提供的任何帮助!我将是第一个承认我的组件很生锈的人。

【问题讨论】:

    标签: c++ windows assembly x86-64 masm


    【解决方案1】:

    您可以让 gcc 为您创建 asm 文件(gcc 也可以生成 MASM 语法):

    gcc -S -masm=intel myfile.c
    

    【讨论】:

      【解决方案2】:

      比较两个版本似乎有些出入:

      movq $0x0, 0x00(%0)
      

      看起来rax 没有被保存,而是内存槽被清零了。

      leaq (%%rip), %%rdx
      

      你应该可以把它翻译成 intel synatx:

      lea rdx, [rip]
      

      这在您使用 64 位相对寻址模式时有效。

      而且这一行是从 att 错误地翻译过来的:

      call $ + 5
      mov rdx, [rax+80h] ; looks reversed
      pop rdx
      

      我是这样翻译上面的原始气体语法的:

      mov qword ptr [rcx], 0
      mov [rcx + 0x08], rbx
      mov [rcx + 0x10], rax 
      mov [rcx + 0x18], rdx 
      mov [rcx + 0x20], rbp 
      mov [rcx + 0x28], rsp 
      mov [rcx + 0x30], rsi 
      mov [rcx + 0x38], rdi 
      mov [rcx + 0x40], r8
      mov [rcx + 0x48], r9
      mov [rcx + 0x50], r10
      mov [rcx + 0x58], r11
      mov [rcx + 0x60], r12
      mov [rcx + 0x68], r13
      mov [rcx + 0x70], r14
      mov [rcx + 0x78], r15
      lea rdx, [rip]
      mov [rcx + 0x80], rdx
      mov rdx, [rcx + 0x18]  ; restore old rdx since it's on clobber list
      

      请注意,我将rcx 切换为rax 只是为了节省额外的mov。所以rax 在gas 语法中被保存在rcx 的位置。您可能需要根据您的不变量来修改它。

      如果它仍然崩溃,我建议使用调试器逐步完成它。

      【讨论】:

      • 感谢您的回答。我仍然不确定如何解决相对寻址模式问题。如原始问题中所述,我正在使用 MS VS 2010 并且 ml64 不想编译 [rip]。错误状态为“错误 A2006:未定义符号:撕裂”。是否有开关或其他东西可以启用 rip 使用?我在 MSDN 上查看了这里,似乎有可能? msdn.microsoft.com/en-us/library/windows/hardware/…
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-09
      • 2011-04-26
      • 1970-01-01
      • 1970-01-01
      • 2012-05-22
      • 1970-01-01
      相关资源
      最近更新 更多