jake1036

Linux内核完全剖析之读书笔记<二>

      
                                                                            C语言与汇编语言的相互调用
   1 GNU可以把一些变量值放在CPU寄存器中,即所谓寄存器变量, 节省了CPU访问存储器的时间。
      在嵌入汇编语句中把汇编指令的输出直接写到指定的寄存器中,那么此时应该使用局部寄存器变量。
      在linux内核中只会使用局部寄存器变量。 
          
      在GNU C程序中我们在函数中定义了一个局部寄存器变量如下:
         register int res  _asm_   ("ax") ;
        变量res 希望使用的寄存器是 eax 。 但是变量不一定会存储在该寄存器中,但是如果该变量用作asm的操作数,
        那么还是能够保证指定的寄存器被用作该操作数。

 内联函数 
     在程序中,一个函数若声明为Inline,那么就可以让gcc把函数的代码集成到调用该函数的代码中去。
      这样处理就会节省函数调用时进入/退出的时间开销。

3 C与汇编函数的相互调用      
      (1) 栈帧结构和控制转移权方式 
          CPU使用栈来支持函数调用操作,栈被用来传递参数、存储返回信息、临时保存寄存器原有值和存储局部数据。 
          单个函数调用操作所使用的部分被称为栈帧结构。
          栈帧结构由两个指针指定,esp为栈指针,ebp为帧指针。 
        
   
    




   栈是往小的地方扩展,esp指向当前栈顶的元素,通过使用push和pop可以完成数据的出入栈操作。


 4 指令CALL 和 指令RET
    指令CALL的作用是把返回地址压入栈中,并且跳转到被调用函数开始处执行。
   返回地址是指的是 紧随调用CALL后面一条指令的地址,因此当被调函数返回时,就会从该位置继续执行。
  
   RET指令用于弹出栈顶处的指针并跳到该地址处。在使用该指令之前,首先应该正确处理栈中的内容,使得
  当前栈指针所指位置的内容正好是先前CALL指令所保存的返回地址。   另外如果返回值是一个整数或者是指针的话,
  那么寄存器eax将被默认用来传递返回值。 
 
5 在汇编语言中调用C 函数

   调用方法如下: 
    程序需要首先按照逆向的顺序把函数参数压入到堆栈中,即函数的最右边一个先入栈,
    而最左边的一个参数在最后调用指令之前入栈。
     函数调用栈如下:

     
     
    由上图可知一旦参数压栈完毕,则随之将CALL指令后的一个指令地址压栈(即Return Address的值)。




   








  















posted on 2010-09-16 10:27 kahn 阅读(512) 评论(0)  编辑 收藏 引用


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理