在汇编中实现简单的64位Windows功能

时间:2018-11-28 23:45:51

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

由于VC ++编译器中的this bug,我要将部分代码从C ++移植到汇编中。 VC ++不支持64位目标的内联汇编,因此我不得不创建一个汇编文件。

为什么以下 empty 函数在运行时崩溃,提示“访问冲突执行位置0x0000000000000000”?

C ++部分:

extern "C"
{
    void asm_proc( const void* p1, const void* p2, void* p3 );
}

int main()
{
    asm_proc( nullptr, nullptr, nullptr );
    return 0;
}

组装部分:

PUBLIC asm_proc

; Save the non-volatile XMM registers to the stack starting from specified offset. This uses 160 = A0h bytes of the stack.
; https://docs.microsoft.com/en-us/cpp/build/register-usage?view=vs-2017#register-volatility-and-preservation
SAVE_XMM_REGS macro offset
    movaps [ rsp + offset ], xmm6
    movaps [ rsp + offset + 10h ], xmm7
    movaps [ rsp + offset + 20h ], xmm8
    movaps [ rsp + offset + 30h ], xmm9
    movaps [ rsp + offset + 40h ], xmm10
    movaps [ rsp + offset + 50h ], xmm11
    movaps [ rsp + offset + 60h ], xmm12
    movaps [ rsp + offset + 70h ], xmm13
    movaps [ rsp + offset + 80h ], xmm14
    movaps [ rsp + offset + 90h ], xmm15
endm

; Restore XMM registers from the stack.
LOAD_XMM_REGS macro offset
    movaps xmm15, [ rsp + offset + 90h ]
    movaps xmm14, [ rsp + offset + 80h ]
    movaps xmm13, [ rsp + offset + 70h ]
    movaps xmm12, [ rsp + offset + 60h ]
    movaps xmm11, [ rsp + offset + 50h ]
    movaps xmm10, [ rsp + offset + 40h ]
    movaps xmm8,  [ rsp + offset + 20h ]
    movaps xmm7,  [ rsp + offset + 10h ]
    movaps xmm6,  [ rsp + offset ]
endm

.CODE

align(16)
asm_proc PROC FRAME
; const void* p1: rcx
; const void* p2: rdx
; void *p3: r8

    ; Some boilerplate copy-pasted from this repository: https://github.com/lallousx86/AsmInVs/tree/master/x64asm

    ; Prologue
    sub rsp, 030h ; allocate stack space
    .allocstack 030h ; encode that change
    push rbp ; save old frame pointer
    .pushreg rbp ; encode stack operation
    mov rbp, rsp ; set new frame pointer
    .setframe rbp, 0 ; encode frame pointer
    .endprolog

    ; Need stack space for XMM6-15 registers, they're non-volatile
    sub rsp, 0C0h

    ; Save non-volatile registers we use.
    ; https://docs.microsoft.com/en-us/cpp/build/register-usage?view=vs-2017#register-volatility-and-preservation
    mov QWORD ptr [ rsp ], r12
    mov QWORD ptr [ rsp + 8 ], r13
    mov QWORD ptr [ rsp + 10h ], r14
    mov QWORD ptr [ rsp + 18h ], r15
    SAVE_XMM_REGS 20h

    ; Actual code goes here, stripped out.

    ; Restore non-volatile registers
    LOAD_XMM_REGS 20h
    mov r15, QWORD ptr [ rsp + 18h ]
    mov r14, QWORD ptr [ rsp + 10h ]
    mov r13, QWORD ptr [ rsp + 8 ]
    mov r12, QWORD ptr [ rsp ]

    add rsp, ( 0C0h + 030h )
    pop rbp
    ret

asm_proc ENDP

END

P.S。我的函数没有调用任何其他函数,只是一个叶子函数。我删除的实际代码确实使用了r12-15和xmm6-15,因此我需要保留它们see the ABI

0 个答案:

没有答案