x264_stack_align( x264_slice_write, h )解读



    看到x264中对于字节对齐的函数x264_stack_align( x264_slice_write, h ),为什么要字节对齐呢?因为x264中用到的指令集优化SSE2,而SSE2寄存器是128位寄存器,SSE2的指令是对16字节(128/8)同时处理,这就要求指令作用时,数据存放的地址以16字节对齐(即数据地址是16的倍数),这样一个指令周期就可以处理数据,不然会消耗多个指令周期而发挥不了指令集优化的性能。

    在x264_stack_align( x264_slice_write, h )上设置断点,进行反汇编跟踪


    x264_stack_align( x264_slice_write, h );
0040F130  mov         eax,dword ptr [h] 
0040F133  push        eax  
0040F134  push        offset x264_slice_write (40F180h) 
0040F139  call        _x264_stack_align (412990h) 
0040F13E  add         esp,8 



如图结合汇编程序,分别将参数h,x264_slice_write的函数地址压栈,接着调用call至_x264_stack_align处,调用call时例行对返回地址压栈


_x264_stack_align:
00412990  push        ebp  
00412991  mov         ebp,esp 
00412993  sub         esp,4 
00412996  and         esp,0FFFFFFF0h 
00412999  mov         ecx,dword ptr [ebp+8] 
0041299C  mov         edx,dword ptr [ebp+0Ch] 
0041299F  mov         dword ptr [esp],edx 
004129A2  call        ecx  

程序跳至_x264_stack_align处,首先将ebp值压栈,接着将esp的值赋给ebp,ebp指在图中所示处,然后esp = esp - 4,如图所指。接着执行and         esp,0FFFFFFF0h ,这边esp被调整到16的倍数如图所示调整后esp下移(esp本身就是16的倍数时在原位置不变),这边即是实现了16字节的对齐。然后将x264_slice_write的函数入口地址赋给ecx,将h赋给edx,并将edx压入栈中,call ecx程序跳转至x264_slice_write处。


static void x264_slice_write( x264_t *h )
{
0040F180  push        ebp  
0040F181  mov         ebp,esp 
0040F183  sub         esp,120h 
0040F189  push        ebx  
0040F18A  push        esi  
0040F18B  push        edi  
0040F18C  lea         edi,[ebp-120h] 
0040F192  mov         ecx,48h 
0040F197  mov         eax,0CCCCCCCCh 
0040F19C  rep stos    dword ptr es:[edi] 


接着跳转到x264_slice_write处,push ebp,参数值h可以通过dword ptr [ebp+8] 索引到。

转载请注明出处。。。

转载 : https://blog.csdn.net/diffenyu/article/details/8257906


猜你喜欢

转载自blog.csdn.net/yanceyxin/article/details/82013023