zoukankan      html  css  js  c++  java
  • Linux汇编与C互相调用

    一. 概述

              汇编通过call指令调用C函数,call指令主要有两个功能:1.将下一条指令的地址保存在栈顶;2.设置eip指向被调用程序代码的开始处。汇编使用ret指令返回,ret的功能是把返回地址从桟里弹出,并转到该地址去执行。

            汇编程序调用C函数时,函数的入口参数使用堆栈来传送。

            C函数调用时,输入参数采用堆栈方式传递,参数的传递顺序是从右到左,调用者负责清除参数占用的堆栈空间。

            C函数的返回值如果是32位整数则存在eax寄存器,如果是64位整数,则存在edx:eax寄存器。

    二. 实现

           下面的程序由2个文件组成,一个是assembly.s,另外一个是gnuc.c。程序的功能是:在gnuc.c里定义一个全局变量i,在main()函数里调用assembly.s文件里的a_add()函数,将变量i的地址作为参数传进去,在a_add()函数里将变量i的值加1,然后调用gnuc.c文件里的c_add()函数,参数也是变量i的地址,在c_add()函数里将参数所指的值加1,最后main()里打印变量i的值。

    gnuc.c的代码:

     1 #include<stdio.h>
     2 
     3 static int i = 0;
     4 
     5 
     6 void c_add(int *k)
     7 {
     8     (*k)++;
     9 } 
    10 
    11 int main(void)
    12 {    
    13     a_add(&i);
    14     printf("%d\n",i);
    15 
    16     return 0;
    17 }

    assembly.s的代码:

     1 .section .text
     2 .type a_add,@function
     3 .globl a_add
     4 a_add:
     5     pushl %ebp        #现场保护
     6     movl %esp,%ebp
     7 
     8     movl 8(%ebp),%eax #取得C函数传过来的参数
     9     pushl %ecx        #保护ecx,用作临时变量
    10     movl (%eax),%ecx  #取得指针所指的内容
    11     addl $1,%ecx      #将内容+1
    12     movl %ecx,(%eax)  #将内容放回指针所指的地方
    13     popl %ecx         #恢复ecx
    14     pushl %eax        #压桟,以便传参给C函数
    15     call c_add        #调用C函数
    16 
    17     addl $4,%esp      #清理局部变量
    18     popl %ebp         #恢复现场
    19     ret               #返回

    运行结果:

           可见程序输出2,符合预期效果。

  • 相关阅读:
    明白python文件如何组织,理解建立源文件
    Python特殊语法:filter、map、reduce、lambda [转]
    html标签属性大全
    使用Webdriver执行JS小结
    Sublime Text ——3200破解补丁
    JavaScript——JS屏蔽F12和右键
    Typecho——数据库无法连接问题
    vscode——配置git的path
    windows电脑连接蓝牙耳机的正确步骤
    eolinker——添加项目成员
  • 原文地址:https://www.cnblogs.com/lknlfy/p/2598074.html
Copyright © 2011-2022 走看看