Created
March 7, 2025 02:36
-
-
Save david4958606/611bd62714d470a3991952e29e6a3aba to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 编译器和汇编器 | |
CC = gcc | |
NASM = nasm | |
# 编译、汇编和链接选项 | |
# -nostdlib 和 -nostartfiles 用于防止引入系统启动文件和标准库 | |
CFLAGS = -static -O2 -nostdlib -nostartfiles -Wall -Wextra -m64 | |
LDFLAGS = -static -m64 -nostdlib -nostartfiles | |
ASMFLAGS = -f elf64 | |
# 目标文件和生成的可执行文件名 | |
TARGET = mysh | |
OBJS = mysh.o syscalls.o | |
all: $(TARGET) | |
$(TARGET): $(OBJS) | |
$(CC) $(LDFLAGS) -o $@ $(OBJS) | |
mysh.o: mysh.c | |
$(CC) $(CFLAGS) -c -o $@ mysh.c | |
syscalls.o: syscalls.asm | |
$(NASM) $(ASMFLAGS) -o $@ syscalls.asm | |
clean: | |
rm -f $(TARGET) $(OBJS) | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define _GNU_SOURCE | |
#include <sys/types.h> | |
#define NULL ((void*)0) // 手动定义 NULL | |
// 声明汇编函数 | |
ssize_t syscall_read(int fd, void* buf, size_t count); | |
ssize_t syscall_write(int fd, const void* buf, size_t count); | |
pid_t syscall_fork(void); | |
int syscall_execve(const char* path, char* const argv[], char* const envp[]); | |
pid_t syscall_wait4(int pid, int* status, int options, void* rusage); | |
void syscall_exit(int status); | |
#define MAX_ARGS 64 | |
#define MAX_LINE 1024 | |
// 自定义简单参数分割 | |
int split_args(char* line, char** args) | |
{ | |
int i = 0; | |
while (*line != '\0' && i < MAX_ARGS - 1) | |
{ | |
while (*line == ' ') | |
*line++ = '\0'; | |
if (*line) | |
args[i++] = line; | |
while (*line && *line != ' ') | |
line++; | |
} | |
args[i] = NULL; | |
return i; | |
} | |
void _start() | |
{ | |
char cmd[MAX_LINE]; | |
char* args[MAX_ARGS]; | |
const char prompt[] = "mysh> "; | |
while (1) | |
{ | |
syscall_write(1, prompt, sizeof(prompt) - 1); | |
ssize_t len = syscall_read(0, cmd, MAX_LINE); | |
if (len <= 0) | |
syscall_exit(1); | |
cmd[len - 1] = '\0'; // 去掉换行符 | |
if (!split_args(cmd, args)) | |
continue; | |
if (args[0][0] == 'e' && args[0][1] == 'x' && args[0][2] == 'i' | |
&& args[0][3] == 't' && args[0][4] == '\0') | |
{ | |
syscall_exit(0); | |
} | |
pid_t pid = syscall_fork(); | |
if (pid == 0) | |
{ // 子进程 | |
syscall_execve(args[0], args, NULL); | |
const char err[] = "execve failed\n"; | |
syscall_write(2, err, sizeof(err) - 1); | |
syscall_exit(1); | |
} | |
else if (pid > 0) | |
{ // 父进程 | |
syscall_wait4(pid, NULL, 0, NULL); | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
; syscalls.asm | |
section .text | |
global syscall_read, syscall_write, syscall_execve | |
global syscall_fork, syscall_wait4, syscall_exit | |
; ssize_t syscall_read(int fd, void *buf, size_t count) | |
syscall_read: | |
mov rax, 0 ; sys_read | |
syscall | |
ret | |
; ssize_t syscall_write(int fd, const void *buf, size_t count) | |
syscall_write: | |
mov rax, 1 ; sys_write | |
syscall | |
ret | |
; pid_t syscall_fork(void) | |
syscall_fork: | |
mov rax, 57 ; sys_fork | |
syscall | |
ret | |
; int syscall_execve(const char *filename, char *const argv[], char *const envp[]) | |
syscall_execve: | |
mov rax, 59 ; sys_execve | |
syscall | |
ret | |
; pid_t syscall_wait4(int pid, int *status, int options, struct rusage *rusage) | |
syscall_wait4: | |
mov rax, 61 ; sys_wait4 | |
syscall | |
ret | |
; void syscall_exit(int status) | |
syscall_exit: | |
mov rax, 60 ; sys_exit | |
syscall | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment