我有以下用nasm语法编写的函数:
global _denseToDenseAddRelAVX_nocache_32_linux
_denseToDenseAddRelAVX_nocache_32_linux:
push ebp
mov ebp, esp
push eax
push ecx
push edx
push edi
push esi
; edi: address1 [ebp + 8]
; esi: address2 [ebp + 12]
; edx: address3 [ebp + 16]
; ecx: count [ebp + 20]
; xmm0: lambda [ebp + 24]
; xmm2: relTolerance [ebp + 32]
mov edi, [ebp+8]
mov esi, [ebp+12]
mov edx, [ebp+16]
mov ecx, [ebp+20]
movlpd xmm0, [ebp+24]
movlpd xmm2, [ebp+32]
mov eax, ecx
shr ecx, 2
and eax, 0x03
vzeroupper
vmovupd ymm5, [abs_mask]
sub esp, 16 ; make space for 2 doubles
movlpd [ebp - 8], xmm2
movlpd [ebp - 16], xmm0 ; <------ THIS LINE IS WRONG
add esp, 16
pop esi
pop edi
pop edx
pop ecx
pop eax
mov esp, ebp
pop ebp
ret
如果删除行movlpd [ebp - 16],xmm0,我的软件可以正常工作,但如果没有,程序会崩溃。如果我使用8,9,10,11,12,13和14而不是16,我的软件再次工作。当然,我使用最后9行进行调试,即我之前从函数返回。这段代码有什么问题? 我在32位保护模式环境中,我从c ++调用此函数。
答案 0 :(得分:3)
将数据写入[ebp - 8]
和[ebp - 16]
这里很糟糕,因为它会破坏已保存寄存器的值,写入[ebp - 16]
特别糟糕,因为它会破坏被调用者保存寄存器{ {1}}。
未经测试,请尝试避免破坏已保存的寄存器,如下所示:
edi
答案 1 :(得分:1)
你b.put(23, z)
,你可能意味着存储相对于make space for 2 doubles
而不是esp
,但无论如何你通过清理堆栈立即抛弃这两个值。你需要重新考虑如何将值返回给调用者。
ebp