139 lines
3.7 KiB
ArmAsm
139 lines
3.7 KiB
ArmAsm
; このサーバーのコードはは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
|
||
|
||
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
|
||
|
||
; 終了(CTRL+C)
|
||
mov rax, 1 ; sys_exit
|
||
xor rdi, rdi
|
||
syscall
|
||
|
||
error_exit:
|
||
mov rax, 1 ; sys_exit
|
||
mov rdi, 1
|
||
syscall
|