How to call function from register view

After I read the books<CS: APP>, I think that comprehend relationship between usage of register and function called is very important to improve our development programming skill, and could make our programming more effective.
 
It’s commonly conception about “Function call” in the high-level language, but it still a little difficult to handle the theory through assembly language way. This article will involves the knowledge assemble language related such as some conception of Register, data instruction.
 
 Programs are translated buy other programs into different form:
  The preprocessor modifies the original C program according to directives that begin with the # character, they will insert the file which #include command point to, then enlarge the macro. For the second step, C compilers generate an output file which is assembly language. At the following steps, the assembler translates the assembly language into machine-language which is a binary file whose bytes encode. Finally, generate a executable object file that is ready to be loaded into memory and executed by the system.
      Preprocessing->Compilation->Assembly->Linking->Loaded
 
 Equivalent assembly language :It’s difficult for us to read object code, but equivalent assembly language is very closely to object code, so it was a valiant attempt to handle the equivalent assemble language skills.
 
 Data instruction & Register: Know the usage of regular rules about instruction, such as MOV, LEA. And there are some differences on instruction’s usage. For example: mov ebp esp means put the value from register esp into ebp.
 
Stack Frame Structure: IA32 programs make use of the program stack to support procedure calls, the stack is used to pass procedure arguments, to store return information, to save register for later restoration, and for local storage. The portion of the stack allocated for a single procedure call is called a stack frame. But there need notify: system just only allocates a stack frame for each procedure but the usage of register is sharing way. The topmost stack frame is delimited by two pointers, with register %ebp serving as the frame pointer, and register %esp serving as the stack pointer.
 
Near calls and Far calls: For sub procedure, there are two types of calls, near calls and Far calls. The formers return address spend 4 bytes, and the later is 8 bytes.
 
   Notify: In this article, so many assembly knowledge be involved
 Ok, base on materials prepared, we could begin our contents. Following code give us instance about 2 function calls
-----------------------------------------------------------------------   
int swap_add(int *xp,int *yp)
       {
              int x=*xp;
              int y=*yp;
 
              return x+y;
       }
      
int caller()
       {
              int arg1=534;
              int ary2=1057;
              int sum=swap+add(&arg1,&arg2);
             
              return 0
       }
main()
{
       caller();
}
-----------------------------------------------------------------------
Caller () called swap_add(), and transfer their argument by address value. Now we reach on argument transferring, function calls, usage of register and stack through equivalent assembly language
-----------------------------------------------------------------------
10:   int caller()
11:   {
00401070   push      ebp           //push %ebp into stack frame, %esp point to the top of stack all the time
                                                                             
00401071   mov       ebp,esp      // to assign value of top stack to %ebp, at this time, %esp=%ebp
                                                              
 
00401073   sub        esp, 4Ch    //%esp-48h, prepare for space of memory to input Variable in the following steps
 
00401076   push       ebx        // the callee
00401077   push       esi     
00401078   push       edi     
00401079   lea         edi,[ebp-4Ch]
0040107C   mov       ecx,13h
00401081   mov       eax,0CCCCCCCCh
00401086   rep stos   dword ptr [edi]
12:       int arg1 = 534;
00401088   mov       dword ptr [ebp-4],216h    // assign value 216h into &ebp-4
13:       int arg2 = 1057;
0040108F   mov       dword ptr [ebp-8],421h   
14:       int sum = swap_add( &arg1, &arg2);
00401096   lea        eax,[ebp-8]                       
00401099   push      eax
0040109A   lea        ecx,[ebp-4]                        
0040109D   push      ecx
0040109E   call        @ILT+5(_swap_add) (0040100a)     // call swap_add()
 
 
 
004010A3   add         esp,8                                                    
004010A6   mov         dword ptr [ebp-0Ch],eax
15:
16:        return 0;
004010A9   xor         eax,eax
17:
18:   }
004010AB   pop         edi
004010AC   pop         esi
004010AD   pop         ebx
004010AE   add         esp,4Ch
004010B1   cmp         ebp,esp
004010B3   call        __chkesp (00401110)
004010B8   mov         esp,ebp
004010BA   pop         ebp
004010BB   ret
---------------------------------------------------------------------------
1:    #include <stdio.h>
2:    int swap_add(int *xp, int *yp)
3:    {
00401030   push        ebp                                               
00401031   mov         ebp,esp                      
00401033   sub         esp,48h                                                                                                              
00401036   push        ebx                                   
00401037   push        esi                                   
00401038   push        edi                                                                                                                     
00401039   lea         edi,[ebp-48h]
0040103C   mov         ecx,12h
00401041   mov         eax,0CCCCCCCCh
00401046   rep stos    dword ptr [edi]                              
4:        int x = *xp;
00401048   mov         eax,dword ptr [ebp+8]    //. chart 1
        
 
0040104B   mov         ecx,dword ptr [eax]
0040104D   mov         dword ptr [ebp-4],ecx                     
                                                                                        
5:        int y = *yp;
00401050   mov         edx,dword ptr [ebp+0Ch]              
00401053   mov         eax,dword ptr [edx]
00401055   mov         dword ptr [ebp-8],eax                     
6:
7:        return x + y;
00401058   mov         eax,dword ptr [ebp-4]
0040105B   add         eax,dword ptr [ebp-8]                      eax
8:    }
0040105E   pop         edi
0040105F   pop         esi
00401060   pop         ebx
00401061   mov         esp,ebp
00401063   pop         ebp
00401064   ret                                                                     
--------------------------------------------------------------------------------------
 
 
                               
address                  stack
        
                  
        ├──────┤
                ebp    
         ├─ ┄┄┄┄─┤
         2 16h (arg1)
        ├─ ┄┄┄┄─┤        
        216h (arg1)
        ├─ ┄┄┄┄─┤
         4ch 的空间   
                                             call() structure of stack frame
        
                
                         
        ├─ ┄┄┄┄─┤
         ebx/esi/edi
        ├──────┤ 
             &arg2    
        ├──────┤
             &arg1      --------|
        ├──────┤                |
        
   返回地址                 | (ebp+8 access to &arg1) chart 1
        ├──────┤               |                       |
               ebp       _________|                       |
         ├─ ┄┄┄┄─┤                                        |
                  x      │← --------------------------|
        ├─ ┄┄┄┄─┤        
                 y     
        ├─ ┄┄┄┄─┤
         48h 的空间   
                                          swap_add() structure of stack frame
        
                
                         
        ├─ ┄┄┄┄─┤
         ebx/esi/edi
        ├──────┤ 
                       
                       
                        │ 
        ├─ ┄┄┄┄─┤ 
Finally, we have finished the introduction. For each function or producer, system allocated the stack frame for them. And we could divide the hole code into three parts: initialization of stack frame; execute; recover the stack frame;
In my opinion, handle some knowledge which assembly related is very useful for us. We could improve our major foundation by practice and thinking.   
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值