一. READ
1. 选择3号系统调用read
2. 使用库函数API触发一个系统调用
编写一个read.c程序如下,使用编译指令运行。程序运行,输入一些文字后,程序会输出刚才输入的内容。
#include <stdio.h>
#include <unistd.h>
#define BUFFER_SIZE 1024
int main() {
char buffer[BUFFER_SIZE];
ssize_t bytesRead;
bytesRead = read(0, buffer, sizeof(buffer) - 1);
if (bytesRead < 0) {
perror("INPUT NULL");
return 1;
}
buffer[bytesRead] = '\0';
printf("%s", buffer);
return 0;
}
3. C代码中嵌入汇编代码触发一个系统调用
可以用汇编语言来触发系统调用,编写一个readasm.c程序且编译运行如下:
#include <stdio.h>
#define BUFFER_SIZE 1024
int main() {
char buffer[BUFFER_SIZE];
ssize_t bytesRead;
asm volatile (
"mov $0, %%rax;" // 设置系统调用号为0 (read)
"mov $0, %%rdi;" // 文件描述符0 (stdin)
"mov %1, %%rsi;" // 设置缓冲区地址
"mov %2, %%rdx;" // 设置读取的最大字节数
"syscall;" // 触发系统调用
"mov %%rax, %0;" // 将返回值放入bytesRead
: "=r" (bytesRead)
: "r" (buffer), "r" (sizeof(buffer) - 1)
: "rax", "rdi", "rsi", "rdx", "memory"
);
if (bytesRead < 0) {
perror("INPUT NULL");
return 1;
}
buffer[bytesRead] = '\0';
printf("%s", buffer);
return 0;
}
二. RANAME
1. 使用库函数API触发
rename.c程序及编译运行结果如下:
#include<stdio.h>
int main(){
int ret;
char *oldname="hello.c";
char *newname="newhello.c";
ret = rename(oldname,newname);
if(ret == 0)
printf("Rename ok");
else
printf("Rename failed");
return 0;
}
2. C代码中嵌入汇编代码触发
renameasm.c程序及编译运行结果如下:
#include<stdio.h>
int main(){
int ret;
char *oldname="hello.c";
char *newname="newhello.c";
asm volatile(
"mov $82, %%rax;"
"mov %1, %%rdi;"
"mov %2, %%rsi;"
"syscall;"
"mov %%eax, %0;"
: "=r"(ret)
: "r"(oldname), "r"(newname)
: "%rax", "%rdi", "%rsi", "%rdx", "%rcx", "%r8", "%r9", "%r10", "%r11", "memory"
);
if(ret == 0)
printf("Rename ok");
else
printf("Rename failed");
return 0;
}
3. syscall
syscall.c程序及编译运行结果如下:
#include<stdio.h>
#include<sys/syscall.h>
int main(){
int ret;
char *oldname="hello.c";
char *newname="newhello.c";
ret = syscall(SYS_rename,oldname,newname);
if(ret ==0)
printf("Rename ok!");
else
printf("Rename failed");
return 0;
}
三. 总结
系统调用是用户空间程序与操作系统内核之间的接口,允许用户空间程序请求操作系统内核提供的服务,如文件操作、进程控制、网络操作等。它们是安全的机制,因为它们通过预定义的接口在用户空间和内核空间之间建立了明确的边界。