x264_stack_align html
爲何要對齊,由於AVX2指令須要32字節對齊。 函數
怎麼對齊,在common/x86/cpu-a.asm spa
一句話,就是模擬一個空調用,這個調用只是對齊堆棧和轉調真實的函數 .net
%if ARCH_X86_64
;-----------------------------------------------------------------------------
; void stack_align( void (*func)(void*), void *arg );
;-----------------------------------------------------------------------------
cglobal stack_align
push rbp ;保存幀寄存器
mov rbp, rsp ;保存rsp
%if WIN64
sub rsp, 32 ; shadow space win64的調用慣例規定,請參看http://wiki.lazarus.freepascal.org/Win64/AMD64_API#Shadow_space
%endif
and rsp, ~31 ;保證32byte對齊。其實一句話,上面是模擬一個函調調用,並把堆棧指針32byte對齊,注意和下面的leave呼應。
mov rax, r0 ;把真實函數指針付給rax
mov r0, r1 ;把參數移到真實函數的參數中,真實函數應該不會使用多餘三個的參數 :)
mov r1, r2
mov r2, r3
call rax ;呼叫真實函數
leave ;恢復rsp,rbp,也就是模擬的函數調用返回,
ret
%else
cglobal stack_align
push ebp
mov ebp, esp
sub esp, 12 ;預留堆棧空間,保存至少三個參數
and esp, ~31 ;對齊堆棧
mov ecx, [ebp+8] ;把第一個參數,真實的函數賦值給ECX, +8跳過old EIP和old EBP ,參考 http://www.unixwiz.net/techtips/win32-callconv-asm.html
mov edx, [ebp+12] ; 把後續的三個參數放在堆棧上
mov [esp], edx
mov edx, [ebp+16]
mov [esp+4], edx
mov edx, [ebp+20]
mov [esp+8], edx
call ecx ;呼叫真實的函數
leave ;退出當前虛擬的函數調用
ret
%endif
unix