2022-2023-1 20222814 《Linux内核原理与分析》第五周作业

2022-2023-1 20222814 《Linux内核原理与分析》第五周作业

实验四 使用库函数和C代码中嵌入汇编代码实现系统调用

前置知识

系统调用的三层机制:
API(应用程序编程接口)
中断向量(系统调用处理入口)
服务程序(系统调用内核处理系统)

内核态&用户态:
计算机的硬件资源是有限的,为了减少有限资源的访问和使用冲突,CPU和操作系统必须提供一些机制对用户程序进行权限划分,Linux系统采用了Intel x86 CPU的0和3两个特权级别,分别对应内核态和用户态。当CPU的执行级别对应的是内核态时,代码可以执行特权指令,访问任意的物理内存。相应的,在用户态,代码能够掌控的范围会受到限制。

用户态和内核态的区分方法:
CS:EIP的指向范围(对于32位的X86机器):
内核态下可以访问0x00000000~0xffffffff的地址空间,共4GB。
用户态下只能访问0x00000000~0xbfffffff的地址空间,不能访问从0xc0000000开始的地址空间。

中断:
一般来说,进入内核态是由中断触发的,系统调用是一种特殊的中断。

中断的类别:
硬件中断:在用户态进程执行时,硬件中断信号到来,进入内核态,就会执行这个中断对应的中断服务例程。
软中断(trap的方式):用户态程序执行的过程中,调用了一个系统调用,陷入了内核态。

1、进入/LinuxKernel/linux-3.18.6/arch/x86/syscalls目录,查看syscall_32.tbl文件,获取系统调用号信息。此次实验选择write,其系统调用号为4,即0x4

在这里插入图片描述
在这里插入图片描述
函数定义:ssize_t write (int fd, const void * buf, size_t count);
函数说明:write()会把参数buf所指的内存写入count个字节到参数fd所指的文件内。
返回值:如果顺利write()会返回实际写入的字节数(len)。当有错误发生时则返回-1,错误代码存入erro中。

2、使用库函数API的方式利用系统调用,编写20222814write.c文件,通过write()返回输入的字符串。

在这里插入图片描述
代码如下:

#include<unistd.h>//unistd.h 是 C 和 C++ 程序设计语言中提供对 POSIX 操作系统 API 的访问功能的头文件的名称。
int main(){
    char *m = "20222814\n";
    write(1,m,9);
    return 0;
}

结果如下:
在这里插入图片描述

3、在C代码中嵌入汇编使用系统调用,修改20222814write.c文件,嵌入汇编代码。

在这里插入图片描述
代码如下:

#include<unistd.h>
int main(){
    char *m = "20222814\n";
    int len = 9;
    int r;
    asm volatile(
			movl $0x4, %%eax\n\t"     //write系统调用号为4
			"movl $0x1, %%ebx\n\t"     //文件描述符1:标准输出stdout
        	"movl %1, %%ecx\n\t"      //要输出的信息
        	"movl %2, %%edx\n\t"      //要输出的长度
        	"movl %%eax, %0\n\t"
        	:"=m"(r)
        	:"c"(m),"d"(len)
                :
	);
}

结果如下:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值