(2023-2024-1)20232830《Linux内核原理分析与设计》第五周作业

(2023-2024-1)20232830《Linux内核原理分析与设计》第五周作业

1. 《庖丁解牛Linux分析》第5章

进程的通信与创建

进程通信
父子进程
进程创建
fork()和exec()系统
fork()和exec()系统

2. 实验四:两种不同方式的系统调用

本次实验为分别使用库函数和C语言嵌入汇编代码的方式对系统进行同一个调用,所选择的是116号系统调用sysinfo
sysinfo

2.1 库函数调用

使用库函数调用sysinfo,代码sysinfo.c如下:

#include<stdio.h>
#include<linux/kernel.h> // 包含 struct sysinfo 消息结构

void main() {
    struct sysinfo si; // 定义 sysinfo 结构体变量 si
    int result;

    result = sysinfo(&si); // 调用 sysinfo() 函数获取系统信息,并将结果存储在 si 变量中

    printf("result=%d\n", result); // 打印获取系统信息的结果,即 sysinfo() 函数的返回值
    printf("total memory=%ld\n", si.totalram); // 打印系统总内存量,以字节为单位
    printf("free memory=%ld\n", si.freeram); // 打印系统空闲内存量,以字节为单位
}

这段代码使用了 <stdio.h> 头文件中的 printf() 函数和 <linux/kernel.h> 头文件中的 struct sysinfo 结构体和 sysinfo() 函数。

  • struct sysinfo 是 Linux 内核提供的一个结构体,用于存储系统的各种信息,如内存使用情况、负载情况等。
  • sysinfo() 函数是一个系统调用,用于获取系统的详细信息,包括内存使用情况等,并将结果存储在传入的 struct sysinfo 变量中。

代码中的主要逻辑如下:

  1. 定义了一个名为 si 的 struct sysinfo 类型的变量,用于存储系统信息。
  2. 调用 sysinfo() 函数,将系统信息存储在 si 变量中,并将返回值赋给 result 变量。
  3. 使用 printf() 函数打印获取到的系统信息,包括 result(sysinfo() 的返回值)、系统总内存量(si.totalram)和系统空闲内存量(si.freeram)。

2.2 C语言内联汇编调用

使用C语言内联汇编调用sysinfo,代码sysinfoc.c如下:

#include<stdio.h>
#include<linux/kernel.h>

int main() {
   struct sysinfo si; // 定义 sysinfo 结构体变量 si
   int result = 100; // 初始化 result 变量为 100
   unsigned long totalram = 0; // 初始化 totalram 变量为 0
   unsigned long freeram = 0; // 初始化 freeram 变量为 0

   asm volatile(
       "mov $116,%%eax\n\t" // 将系统调用号 116(sysinfo)加载到寄存器 eax 中
       "mov %1,%%ebx\n\t" // 将 si 结构体变量的地址加载到寄存器 ebx 中
       "int $0x80\n\t" // 执行中断指令,触发系统调用
       "mov %%eax,%0\n\t" // 将系统调用的返回值存储到 result 变量中
       :"=r"(result) // 输出约束:将结果存储到 result 变量中
       :"b"(&si) // 输入约束:将 si 结构体变量的地址传递给 ebx 寄存器
       : // 无需使用的寄存器
   );

   printf("result=%d\n", result); // 打印系统调用的返回值
   printf("total memory=%ld\n", si.totalram); // 打印系统总内存量,以字节为单位
   printf("free memory=%ld\n", si.freeram); // 打印系统空闲内存量,以字节为单位

   return 0;
}

这段代码主要逻辑如下:

  • 定义了一个名为 si 的 struct sysinfo 类型的变量,用于存储系统信息。
  • 初始化了 result、totalram 和 freeram 变量,分别为 100、0 和 0。
  • 使用内联汇编(Inline Assembly)的方式调用 Linux 内核的系统调用,具体为系统调用号 116(sysinfo)。
    • 使用汇编指令将系统调用号加载到 eax 寄存器中。
    • 使用汇编指令将 si 结构体变量的地址加载到 ebx 寄存器中。
    • 执行中断指令触发系统调用。
    • 将系统调用的返回值存储到 result 变量中。
  • 使用 printf() 函数打印获取到的系统信息,包括 result(系统调用的返回值)、系统总内存量(si.totalram)和系统空闲内存量(si.freeram)。
  • 返回 0 表示程序运行成功。

2.3 运行结果

分别对两个文件进行编译并运行,结果如下:
运行结果

3. 总结

库函数调用和内联汇编调用区别如下:

  • 抽象级别:库函数调用是高级语言中使用函数调用触发系统调用,无需了解底层细节;内联汇编调用直接使用汇编指令触发系统调用,需要了解汇编语言和系统调用的细节。
  • 可移植性:库函数调用具有较好的可移植性,可以在不同平台上编译和运行;内联汇编调用的可移植性较差,特定于底层硬件和操作系统。
  • 简洁性和可读性:库函数调用使代码更简洁和易读;内联汇编调用使代码变得冗长和难以理解。
  • 性能:内联汇编调用系统调用通常具有较好的性能,绕过了库函数调用的开销。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值