前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >原 Linux下嵌入汇编代码调用API(u

原 Linux下嵌入汇编代码调用API(u

作者头像
不高不富不帅的陈政_
发布2018-05-18 15:39:52
2.2K0
发布2018-05-18 15:39:52
举报
文章被收录于专栏:聊聊技术

以下关于fork()的描述来自于:jason314

首先,在Linux环境下,一个进程调用fork()函数后,系统先给新的进程分配资源,例如存储数据和代码的空间。然后把原来的进程的所有值都复制到新的新进程中,只有少数值与原来的进程的值不同。相当于克隆了一个自己。

fork调用的一个奇妙之处就是它仅仅被调用一次,却能够返回两次,它可能有三种不同的返回值:     1)在父进程中,fork返回新创建子进程的进程ID;     2)在子进程中,fork返回0;     3)如果出现错误(如系统资源不足),fork返回一个负值。

在fork函数执行完毕后,如果创建新进程成功,则出现两个进程,一个是子进程,一个是父进程。在子进程中,fork函数返回0,在父进程中,fork返回新创建子进程的进程ID。我们可以通过fork返回的值来判断当前进程是子进程还是父进程。

现在,我们来写一段程序,使用API调用fork:

代码语言:javascript
复制
#include <stdio.h>
#include <unistd.h>

int main()
{
    pid_t fpid;
    int count = 0;
    fpid = fork();
    printf("Now pid = %d\n", fpid);
    if(fpid < 0)
        printf("Error in fork!");
    else if(fpid == 0){
        printf("I am the child process, my process id is: %d\n", getpid());
        count++;
    }
    else{
        printf("I am the parent process, my process id is: %d\n", getpid());
        count++;
    }
    printf("Now count = %d\n", count);
    return 0;
}

在第八行执行完fork后,父进程中有count=0、fpid=子进程的pid;子进程中变量为count=0、 fpid=0,这两个进程的变量都是独立的,存在不同的地址中,也不是共用的。可以说,我们就是通过fpid来识别和操作父子进程的。

在x86的系统中,%eax寄存器在进行系统调用前储存系统调用号。另外,由于六个及以上参数的系统调用并不多见,因此一般使用%ebx、%ecx、%edx、%esi和%edi依次存放前五个参数。如果出现六个以上参数的情况,应该用一个单独的寄存器存放指向所有这些参数在用户空间地址的指针。当调用结束后,函数的返回值存放在%eax中。

下面,我们将改写fork.c,直接嵌入汇编语言进行系统调用:

代码语言:javascript
复制
#include <stdio.h>
#include <unistd.h>

int main()
{
    pid_t fpid;
    int count = 0;
    asm volatile(
            "mov $0, %%ebx\n\t"
            "mov $0x2, %%eax\n\t"
            "int $0x80\n\t"
            "mov %%eax, %0\n\t"
            : "=m"(fpid)
            );
    printf("Now pid = %d\n", fpid);
    if(fpid < 0)
        printf("Error in fork!");
    else if(fpid == 0){
        printf("I am the child process, my process id is: %d\n", getpid());
        count++;
    }
    else{
        printf("I am the parent process, my process id is: %d\n", getpid());
        count++;
    }
    printf("Now count = %d\n", count);
    return 0;
}

总结:API与系统调用并不是一一对应的关系(Linux系统可以参考syscalls),它为程序提供了标准接口。而内核基本只与系统调用打交道;当然,我们也可以直接使用系统调用写程序,但势必会降低程序的可移植性。至于APIs如何进行系统调用,那就是Glibc等标准制定者的事了。

陈政/arc001    原创作品转载请注明出处  《Linux内核分析》MOOC课程

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
对象存储
对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档