commit 7426a775b1f0a7256f235cc10e7953950caee87a Author: 諏訪子 Date: Sun Nov 30 22:03:38 2025 +0900 最初コミット diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3282dd2 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +*.o +*.core +server diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..720de48 --- /dev/null +++ b/Makefile @@ -0,0 +1,12 @@ +all: + nasm -f elf64 main.s -o main.o + ld main.o -o server + +debug: + nasm -f elf64 -g -F dwarf main.s -o main.o + ld main.o -o server + +clean: + rm -rf main.o server + +.PHONY: all debug clean diff --git a/README.md b/README.md new file mode 100644 index 0000000..f267432 --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +x64アセンブリ言語で書かれた概念実証のHTTPサーバー\ +未完了 diff --git a/file.s b/file.s new file mode 100644 index 0000000..df8cd35 --- /dev/null +++ b/file.s @@ -0,0 +1,53 @@ +section .text + +load_file: + ; ファイルの開く + mov rax, 5 ; sys_open + mov rdi, filename + mov rsi, 0 ; O_RDONLY + mov rdx, 0 + mov rax, 499 ; sys_openat + ; mov rax, 547 + ; mov rdi, -100 ; AT_FDCWD + ; mov rsi, filename + ; mov rdx, 0 ; O_RDONLY + ; mov r10, 0 ; モード(見逃し) + syscall + + cmp rax, 0 + jl .fail + mov [filefd], rax + + ; ファイルサイズの受け取り + mov rax, 478 ; sys_lseek + mov rdi, [filefd] + xor rsi, rsi + mov rdx, 2 ; SEEK_END + syscall + + mov [file_size], rax + + ; 初めからシーク + mov rax, 478 + xor rsi, rsi + mov rdx, 0 ; SEEK_SET + syscall + + ; ファイルの全部の読み込み + mov rax, 3 ; sys_read + mov rdi, [filefd] + mov rsi, file_buf + mov rdx, [file_size] + syscall + + ; ファイルを閉じる + mov rax, 6 ; sys_close + mov rdi, [filefd] + syscall + + xor rax, rax ; 成功 + ret + +.fail: + mov rax, -1 + ret diff --git a/main.s b/main.s new file mode 100644 index 0000000..297bf55 --- /dev/null +++ b/main.s @@ -0,0 +1,139 @@ +; このサーバーのコードははFreeBSD向けに書きました。 +; Linuxに実行するには、syscall番号を変更して下さい。 +section .data + filename db "./www/index.html", 0x0 + at_fd dq -0x64 + + listen_msg db "サーバーは http://0.0.0.0:8000/ で実行中・・・", 0xa, 0x0 + listen_len equ $-listen_msg-1 + ; 1101 + + http_header db "HTTP/1.1 200 OK", 0xd, 0xa + db "Content-Type: text/html", 0xd, 0xa + db "Connection: close", 0xd, 0xa + db "Content-Length: " + clen_str db " ", 0xd, 0xa, 0xd, 0xa, 0x0 + + notfound db "HTTP/1.1 404 Not Found", 0xd, 0xa, + db "Content-Length: 0", 0xd, 0xa, 0xd, 0xa, 0x0 + +section .bss + sock resq 0x1 ; サーバーソケット + clientfd resq 0x1 ; クライアントソケット + filefd resq 0x1 + file_size resb 0x400 ; HTMLファイルサイズ + file_buf resb 0x20000 ; 128 KiB + req_buf resb 0x1000 ; 4 KiB + addr resb 0x10 ; sockaddr_in ストラクチャー + +section .text + %include "file.s" + %include "u64todec.s" + global _start + +_start: + mov rax, 4 ; sys_write + mov rdi, 1 ; stdout + mov rsi, listen_msg + mov rdx, listen_len + syscall + + ; ソケットの作成 + mov rax, 97 ; sys_socket + mov rdi, 2 ; PF_INET + mov rsi, 1 ; SOCK_STREAM + mov rdx, 0 ; プロトコール + syscall + + cmp rax, 0 + jl error_exit + mov [sock], rax + + ; 0.0.0.0:8000 にバインド + mov word [addr], 2 ; sin_family = AF_INET + mov word [addr+2], 0x401f ; sin_port = 8000 (ポート番号)、ネットワークのバイト列:0x1f40 + ;mov dword [addr+4], 0x0100007f ; sin_addr = 127.0.0.1(リトルエンディアンで) + mov dword [addr+4], 0 ; sin_addr = INADDR_ANY = 0.0.0.0 + mov qword [addr+8], 0 ; パッディング + + ; バインド + mov rax, 104 ; sys_bind + mov rdi, [sock] + mov rsi, addr + mov rdx, 0x10 + syscall + + cmp rax, 0 + jne error_exit + + ; リッスン + mov rax, 106 ; sys_listen + mov rdi, [sock] + mov rsi, 0xa ; バックログ + syscall + + cmp rax, 0 + jne error_exit + + ; HTMLファイルをメモリに読み込み(一回だけ) + call load_file + test rax, rax + jnz error_exit ; ファイルを見つけなければ、エラーで終了する + +accept_loop: + ; 接続の受け取り + ; mov rax, 30 ; sys_accept + mov rax, 541 ; sys_accept4 + mov rdi, [sock] + mov rsi, 0 + mov rdx, 0 + mov r10, 0 ; フラグ=0 + syscall + + cmp rax, 0 + jl loop_continue + mov [clientfd], rax + + ; リクエストの読み込み + mov rax, 3 ; sys_read + mov rdi, [clientfd] + mov rsi, req_buf + mov rdx, 0xfff + syscall + + ; ヘッダーの送信 + ; Content-Length文字から + mov rax, [file_size] + mov rdi, clen_str + call u64_to_dec + + mov rax, 4 ; sys_write + mov rdi, [clientfd] + mov rsi, http_header + mov rdx, clen_str + 20 - http_header ; ヘッダーの長さ(CRLF含む) + syscall + + ; ファイル内容の送信 + mov rax, 4 ; sys_write + mov rdi, [clientfd] + mov rsi, file_buf + mov rdx, [file_size] + syscall + + ; クライアントの終了 + mov rax, 6 ; sys_close + mov rdi, [clientfd] + syscall + +loop_continue: + jmp accept_loop + +error_exit: + mov rax, 1 ; sys_exit + mov rdi, 1 + syscall + + ; 終了(CTRL+C) + ; mov rax, 1 ; sys_exit + ; xor rdi, rdi + ; syscall diff --git a/u64todec.s b/u64todec.s new file mode 100644 index 0000000..3320ce2 --- /dev/null +++ b/u64todec.s @@ -0,0 +1,33 @@ +section .text + +u64_to_dec: + mov rcx, 10 + mov r8, rdi + lea rdi, [rdi + 0x13] + + test rax, rax + jnz .convert + mov byte [rdi], '0' + dec rdi + jmp .pad + +.convert: + xor rdx, rdx + div rcx + add dl, '0' + mov [rdi], dl + dec rdi + test rax, rax + jnz .convert + +.pad: + inc rdi +.pad_loop: + cmp rdi, r8 + jbe .done + mov byte [rdi], ' ' + inc rdi + jb .pad_loop + +.done: + ret diff --git a/www/index.html b/www/index.html new file mode 100644 index 0000000..3aece4e --- /dev/null +++ b/www/index.html @@ -0,0 +1,12 @@ + + + + + + + ささ + + +

ささ

+ + diff --git a/www/style.css b/www/style.css new file mode 100644 index 0000000..6208b34 --- /dev/null +++ b/www/style.css @@ -0,0 +1,4 @@ +body { + background-color: #232023; + color: #fcfcfc; +}