使用库函数 API 和 C 代码中嵌入汇编代码两种方式使用同一个系统调用

实验四 使用库函数 API 和 C 代码中嵌入汇编代码两种方式使用同一个系统调用

实验内容

选择一个系统调用(13 号系统调用 time 除外),系统调用列表参见 torvalds/linux。

参考视频中的方式使用库函数 API 和 C 代码中嵌入汇编代码两种方式使用同一个系统调用

实验过程

使用库函数API

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>

int main() {
    int fd;
    char buf[1024];
    ssize_t num_read;

    // 打开文件
    fd = open("example.txt", O_RDONLY);
    if (fd == -1) {
        perror("open");
        return 1;
    }

    // 读取文件内容
    num_read = read(fd, buf, sizeof(buf));
    if (num_read == -1) {
        perror("read");
        close(fd);
        return 1;
    }

    // 输出读取的内容
    write(STDOUT_FILENO, buf, num_read);

    // 关闭文件
    close(fd);

    return 0;
}

截图

使用C代码中嵌入汇编代码

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <linux/unistd.h>
#include <asm/unistd.h>

int main() {
    long fd;
    char buf[1024];
    ssize_t num_read;

    // 获取当前工作目录(可选)
    char cwd[1024];
    if (getcwd(cwd, sizeof(cwd)) != NULL) {
        printf("Current working directory: %s\n", cwd);
    } else {
        perror("getcwd error");
    }

    // 使用内联汇编打开文件
    asm volatile (
        "mov %1, %%rax;"    // 将系统调用号放入 rax 寄存器
        "mov %2, %%rdi;"    // 将文件名指针放入 rdi 寄存器
        "mov %3, %%rsi;"    // 将打开模式放入 rsi 寄存器
        "syscall;"          // 调用系统调用
        "mov %%rax, %0;"    // 将返回值存入 fd
        : "=r"(fd)          // 输出操作数
        : "i"(__NR_open), "r"("example.txt"), "i"(O_RDONLY) // 输入操作数
        : "rdi", "rsi", "rax", "memory" // 被修改的寄存器和内存
    );

    printf("File descriptor: %ld\n", fd);

    // 检查文件描述符是否有效
    if (fd < 0) {
        printf("Error opening file: %ld\n", fd);
        return 1;
    }

    // 使用内联汇编读取文件内容
    while (1) {
        asm volatile (
            "mov %1, %%rax;"    // 将系统调用号放入 rax 寄存器
            "mov %2, %%rdi;"    // 将文件描述符放入 rdi 寄存器
            "mov %3, %%rsi;"    // 将缓冲区指针放入 rsi 寄存器
            "mov %4, %%rdx;"    // 将缓冲区大小放入 rdx 寄存器
            "syscall;"          // 调用系统调用
            "mov %%rax, %0;"    // 将返回值存入 num_read
            : "=r"(num_read)    // 输出操作数
            : "i"(__NR_read), "r"(fd), "r"(buf), "i"(sizeof(buf)) // 输入操作数
            : "rdi", "rsi", "rdx", "rax", "memory" // 被修改的寄存器和内存
        );

        printf("Bytes read: %zd\n", num_read);

        if (num_read < 0) {
            perror("read");
            close(fd);
            return 1;
        }

        if (num_read == 0) { // EOF
            break;
        }

        // 输出读取的内容
        ssize_t bytes_written = write(STDOUT_FILENO, buf, num_read);
        if (bytes_written < 0) {
            perror("write");
            close(fd);
            return 1;
        }
    }

    // 关闭文件
    close(fd);
    return 0;
}

截图

posted @ 2025-01-02 11:21  Arisf  阅读(6)  评论(0编辑  收藏  举报