x80指令来执行系统调用,参数使用如下: x86_64引入了一个新指令syscall来执行系统"og:type" content="webpage">x80指令来执行系统调用,参数使用如下: x86_64引入了一个新指令syscall来执行系统" /> x80指令来执行系统调用,参数使用如下: x86_64引入了一个新指令syscall来执行系统"> LINUX系统调用_系统运维_内存溢出

阅读 6

LINUX系统调用,第1张

系统调用

是用户程序和linux内核交互的接口,linux的系统调用有下面三种方式:

在x86与x86_64的系统中,都可以使用int $0x80指令来执行系统调用,参数使用如下:

x86_64引入了一个新指令syscall来执行系统调用,参数使用如下:

正常调用库函数( man 3 execve ),传参方式见 x86 调用约定

查看调用号:头文件 /usr/include/asm/unistd.h 内容如下,所以32位和64位的调用号可以分别在unistd_32.h和unistd_64.h中找到

查看参数: man 2 execve

以 execve 为例, man 2 execve 查看其接口如下: int execve(const char *pathname, char *const argv[], char *const envp[])

下面汇编实现了 execve("/bin/sh", 0, 0) :

32位:

64位:

给个例子给你看看吧,这里是linux中一个C语言程序,他用到了linux提供的系统调用,很长的程序了,或许你没耐心看,我在最后给你列出那些地方用了系统调用

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/msg.h>

#define BUFF_LEN 1024

#define RET_ERROR 1

#define RET_OK 0typedef struct msg_send_struct { //这就是一个消息

的数据结构

long my_type//我们就是根据这个字段来区分每块消息的

char my_text[BUFF_LEN]

} msg_send_struct

int main() {

char * path = "/"

int i_porject_id = 7

key_t key

msg_send_struct msg_send//定义发送消息

int i_ret

int i_msg_idint i_flag = 0666|IPC_CREAT//为消息管道的创建指定参数,IPC_CREAT表示这个消息队列

是创建,而不是搜索已经存在的消息队列

key = ftok(path, i_porject_id)//为消息队列生成一个key,当然你也可以手动指定,当你运气很好没有和已经窜在的消息队列的key起冲突的时候

if(key == 1) {

printf("building key error\n")

exit(1)

}

i_msg_id = msgget(key, i_flag)//根据你的参数决定是创建还是搜索KEY值得消息队列

if(i_msg_id == -1) {

printf("create msg queue error\n")

exit(1)

}

printf("i_msg_id = %d\n", i_msg_id)

msg_send.my_type = 1

strcpy(msg_send.my_text, "hello world")//初始化消息

i_ret = msgsnd(i_msg_id, &msg_send, strlen("hello world") + 1, IPC_NOWAIT)//开始发送,nowait表示如果队列中消息满了当前进程不等待直接返回错误,反之很容易理解吧

if(i_ret == -1) {

printf("msg send error\n")

exit(1)

}

exit(0)

}

下面是系统调用:

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/msg.h>这些头文件可不是库函数,他里面就是linux提供的系统调用。

key = ftok(path, i_porject_id)//为消息队列生成一个key,当然你也可以手动指定,当你运气很好没有和已经窜在的消息队列的key起冲突的时候

linux中系统调用,利用文件系统和ID来创建KEY。

i_msg_id = msgget(key, i_flag)//根据i_flag值决定是创建还是寻找消息队列的系统调用。

i_ret = msgsnd(i_msg_id, &msg_send, strlen("hello world") + 1, IPC_NOWAIT)//发送消息的系统调用msgsnd函数。

这里涉及到进程通信中的消息队列内容,如果不明白没什么关系,可以看出来他和C的库函数调用一模一样,只不过实现方式,这需要你的知识积累到一定程度,有很大差别。对于一个程序员来说,我们看不出什么他们和库函数有什么区别,这算是一种对我们的透明性。

补充:这个例子是我写来学习进程通信内容的,由于采用了linux系统调用,所以只能在linux下面运行,还有就是我没有考虑权限问题,所以要编译请用超级用户root,由于消息队列的特性,这个程序没有释放队列(我把释放代码写在了接受消息的程序中),第2次运行就会报消息队列不能创建的错误。
Linux *** 作系统里面的“系统调用”这一概念相当于Windows上面的API,这样你就明白了吧,懂编程的应该都知道Windows API是个什么东东。所不同的是Linux系统调用的需要包含头文件比较分散,这一点在使用时需要注意,不同的系统调用记得要#include对应的头文件。

欢迎分享,转载请注明来源:

内存溢出

原文地址:

http://outofmemory.cn/yw/7628369.html
创建
(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
如何在 Linux 中产生,加密或解密随机密码
上一篇
2023-04-07
linux如何定义一个容器
2023-04-07

发表评论
请登录后评论... 登录
提交

    评论列表(0条)
保存
{label} {label} x80指令来执行系统调用,参数使用如下: x86_64引入了一个新指令syscall来执行系统', author : '辽宁地质工程职业学院', cat_name : '系统运维', time_y_m : '2023年04月', time_d : '07', site_motto : '内存溢出' }; {script} {script}