使用库函数 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;
}