Assembly HW04_Q01.exe中0x00007FF69997AA5C处引发异常:0xC0000005:访问冲突读取位置0xFFFFFFFFFFFF。发生

Assembly HW04_Q01.exe中0x00007FF69997AA5C处引发异常:0xC0000005:访问冲突读取位置0xFFFFFFFFFFFF。发生,assembly,x86-64,masm,Assembly,X86 64,Masm,我在x64程序集(masm)中编写了一个过程,当代码的执行到达ret station时,它会给出以下错误:在HW04_Q01.exe中0x00007FF69997AA5C处引发异常:0xC000005:访问冲突读取位置0xFFFFFFFFFFFF。发生 getSquareRoot proc .data? temp2 complex <> a real8 ? b real8 ? x real8 ? .data zero real8 0.0

我在x64程序集(masm)中编写了一个过程,当代码的执行到达ret station时,它会给出以下错误:在HW04_Q01.exe中0x00007FF69997AA5C处引发异常:0xC000005:访问冲突读取位置0xFFFFFFFFFFFF。发生

getSquareRoot proc
.data?
    temp2 complex <>
    a real8 ?
    b real8 ?
    x real8 ?
.data
    zero real8 0.0
    _two real8 2.0
    minusOne real8 -1.0
.code
    movsd xmm0, real8 ptr [rsi]
    movsd xmm1, real8 ptr [rsi + 8]
    movsd a, xmm0
    movsd b, xmm1
    mulsd xmm0, a
    mulsd xmm1, b
    movsd xmm2, xmm0
    addsd xmm2, xmm1
    movsd x, xmm2
    movsd xmm1, b
    _IF:
        ucomisd xmm1, zero
        jb _else 
            movsd xmm0,x
            call sqrt
            addsd xmm0, a
            divsd xmm0, _two
            call sqrt
            movsd temp2.real, xmm0

            movsd xmm0,x
            call sqrt
            movsd xmm1, minusOne
            mulsd xmm1, a
            addsd xmm0, xmm1
            divsd xmm0, _two
            call sqrt
            movsd temp2.imag, xmm0
        jmp _endIf
    _else:
            movsd xmm0,x
            call sqrt
            addsd xmm0, a
            divsd xmm0, _two
            call sqrt
            movsd temp2.real, xmm0

            movsd xmm0,x
            call sqrt
            movsd xmm1, minusOne
            mulsd xmm1, a
            addsd xmm0, xmm1
            divsd xmm0, _two
            call sqrt
            mulsd xmm0, minusOne
            movsd temp2.imag, xmm0
    _endIf:
    movsd xmm0, temp2.real
    movsd xmm1, temp2.imag
ret
getSquareRoot endp
getSquareRoot进程
数据
temp2复合体
真的吗?
b真的吗?
x real8?
数据
零实数80.0
_两个Real82.0
minusOne real8-1.0
密码
movsd xmm0,real8 ptr[rsi]
movsd xmm1,real8 ptr[rsi+8]
movsda,xmm0
movsdb,xmm1
mulsd xmm0,a
mulsd xmm1,b
movsd xmm2,xmm0
addsd xmm2,xmm1
movsdx,xmm2
movsd xmm1,b
_如果:
ucomisd xmm1,零
其他
movsd xmm0,x
呼叫sqrt
addsd xmm0,a
divsd xmm0,两个
呼叫sqrt
movsd temp2.real,xmm0
movsd xmm0,x
呼叫sqrt
movsd xmm1,minusOne
mulsd xmm1,a
addsd xmm0,xmm1
divsd xmm0,两个
呼叫sqrt
movsd temp2.imag,xmm0
jmp_endIf
_其他:
movsd xmm0,x
呼叫sqrt
addsd xmm0,a
divsd xmm0,两个
呼叫sqrt
movsd temp2.real,xmm0
movsd xmm0,x
呼叫sqrt
movsd xmm1,minusOne
mulsd xmm1,a
addsd xmm0,xmm1
divsd xmm0,两个
呼叫sqrt
mulsd xmm0,最小1
movsd temp2.imag,xmm0
_endIf:
movsd xmm0,temp2.real
movsd xmm1,temp2.imag
ret
GetSquareRootEndP

实际上,我用助记符sqrtsd替换了对sqrt()C函数的每次调用,因为我处理的值都存储在SSE寄存器(xmm0、xmm1、xmm2,…)中,并且工作正常

您已经破坏了堆栈。检查函数调用。C标准库函数使用一种调用约定,要求调用方清理堆栈。但是我没有对堆栈进行任何推送操作。我如何知道在Windows x64调用约定中,每次C函数调用
call sqrt
clobbers xmm1..5时,需要向esp寄存器添加什么值来清理堆栈。既然您没有进行函数调用,那么您可以像编译器那样将所有值保存在寄存器中,而不是一直对命名变量进行低效的存储/重新加载。