1.给MenuOS增加命令
代码如下
int create_dir(const char *path)
{
int ret;
ret = mkdir(path, 0777);
return ret;
if(-1 ==ret)
{
printf("create dir fail\n");
}
return 0;
}
int mkdir_asm(int argc, char *argv[]) {
int ret;
long mode = 0777;
__asm__ (
"int $0x80;"
: "=a" (ret)
: "0" (SYS_mkdir),
"b" (argv[1]),
"c" (mode)
: "memory", "cc"
);
if (ret < 0) {
perror("create dir fail");
return 1;
}
printf("ok\n");
return 0;
}
2.使用gdb跟踪系统调用内核sys_mkdir
此处用上周写的64位程序来分析代码
int main(int argc, char *argv[]) {
if (argc != 2) {
fprintf(stderr, "使用方法: %s <目录名称>\n", argv[0]);
return 1;
}
int result;
long mode = 0777; // 新目录的权限(八进制表示)。
// 内嵌汇编来执行mkdir系统调用。
// 对于x86_64体系结构,mkdir的系统调用号是83。
// 'syscall' 是某些汇编语言中使用的一条指令。
// 关于系统调用号和它们对应的参数的详细信息可以在Linux内核文档中找到。
__asm__ (
"syscall" // syscall指令要求内核调用在rax(x86_64)中的编号的系统调用。
: "=a" (result) // 系统调用的结果将存储在'result'变量中。
: "0"(83), "D"(argv[1]), "S"(mode) // 83是x86_64架构上'mkdir'系统调用的编号。'D'和'S'用于分别传递系统调用的第一和第二个参数。
: "rcx", "r11", "memory", "cc" // 通知编译器此'asm'块期间这些寄存器和内存可能会更改。
);
// 检查系统调用是否失败
if (result < 0) {
// 出错时,Linux系统调用返回一个负的错误号。
// 我们将其正值存储在'errno'中,然后打印一条消息。
errno = -result;
perror("创建目录时发生错误");
return 1;
}
printf("目录成功创建\n");
return 0;
}