Реализация простой 64-битной функции Windows в сборке - PullRequest
0 голосов
/ 29 ноября 2018

Из-за этой ошибки в компиляторе VC ++ я переносил части своего кода из C ++ в сборку.VC ++ не поддерживает встроенную сборку для 64-битных целей, поэтому я вынужден просто создать файл сборки.

Почему следующая функция empty вылетает во время выполнения, говоря «Выполнение нарушения прав доступаlocation 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

PS Моя функция не вызывает никаких других функций, это конечная функция.Фактический код, который я удалил, использует r12-15 и xmm6-15, поэтому я должен был сохранить их, см. ABI .

...