由于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。