汇编局部变量会导致崩溃

时间:2015-12-27 01:52:22

标签: assembly local

我有以下用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 ++调用此函数。

2 个答案:

答案 0 :(得分:3)

将数据写入[ebp - 8][ebp - 16]这里很糟糕,因为它会破坏已保存寄存器的值,写入[ebp - 16]特别糟糕,因为它会破坏被调用者保存寄存器{ {1}}。

未经测试,请尝试避免破坏已保存的寄存器,如下所示:

edi

答案 1 :(得分:1)

b.put(23, z),你可能意味着存储相对于make space for 2 doubles而不是esp,但无论如何你通过清理堆栈立即抛弃这两个值。你需要重新考虑如何将值返回给调用者。

等等,刚刚注意到关于最后9行的部分。你可能想要的是:

ebp