Assembly HW04_Q01.exe中0x00007FF69997AA5C处引发异常:0xC0000005:访问冲突读取位置0xFFFFFFFFFFFF。发生
我在x64程序集(masm)中编写了一个过程,当代码的执行到达ret station时,它会给出以下错误:在HW04_Q01.exe中0x00007FF69997AA5C处引发异常:0xC000005:访问冲突读取位置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
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寄存器添加什么值来清理堆栈。既然您没有进行函数调用,那么您可以像编译器那样将所有值保存在寄存器中,而不是一直对命名变量进行低效的存储/重新加载。