자동화&툴 리뷰

내 삶에 의미(부족)를 주기 위해 aarch64 어셈블리로 웹 서버 만들기

노동1호 2026. 5. 11. 03:03

내 삶에 의미(부족)를 주기 위해 aarch64 어셈블리로 웹 서버 만들기

내 삶에 의미(부족)를 주기 위해 aarch64 어셈블리로 웹 서버 만들기

개발자 인생이 채워지지 않는 공허함. 프레임워크가 복잡성을 감싸주고, 고수준 언어들이 추상화의 안락한 집을 짓는다. 그 안에서 나는 무엇을 만들고 있을까? 이 질문이 나를 밀어붙였다. 어셈블리어로 웹 서버를 만들자. 그중에서도 현대 인프라의lingua franca가 된 ARM64(AArch64)로. 말 그대로 CPU의lingua franca와 직접 대화하는 것이다.

왜 하필 어셈블리인가

"그냥 다른 언어로 만들면 되잖아"라는 반응이 당연하다. Node.js나 Go는 훨씬 합리적인 선택이다. 그런데 바로 그불합리함 때문에 이 프로젝트에는 의미가 있다. 어셈블리를 직접 짜면 컴퓨터가 어떻게동쿠카 реаль으로 이해하게 된다. TCP 소캣이 커널과 어떻게 데이터를 주고받는지를 syscall만으로 체감하고, HTTP 프로토콜이 어떤 바이트 열로 해석되는지를 직접 코딩하며 배운다.

ymawky라는 프로젝트가 이 길 위의 등불이다. macOS에서 동작하는 순수 ARM64 어셈블리로 쓴 웹 서버로, libc도 없이 syscall만으로 동작한다. 개발자 imtomt는 "웹 서버를 왜 어셈블리로 만드냐"는 질문에 이렇게 대답했다. "내가 컴퓨터를 얼마나 이해하고 있는지 증명하고 싶었기 때문이다."

개발 환경 구축

필수 도구

AArch64 어셈블리로 웹 서버를 만들려면 아래 도구가 필요하다.

ARM64 머신 또는 크로스컴파일러: Apple Silicon Mac이라면 native로 빌드할 수 있다

assembler: GNU Assembler(as) 또는 LLVM의 arm64asm

linker: ld 또는 ld.lld

debugger(선택): lldb 또는 gdb

macOS에서 nasm 대신 .s 확장자의 GNU 어셈블리 문법을 주로 사용한다. Linux에서는 .s 파일을 as로 어셈블하고 ld로 링크하면 된다.

# macOS ARM Mac에서 어셈블리 컴파일 예시as -o server.o server.sld -o server server.o -lobjc -lsystem

프로젝트 구조

순수 어셈블리로 작성된 웹 서버의 전형적인 구조는 다음과 같다.

┌─────────────────────────────────┐│          main.s                 ││  (어셈블리어로 작성된 웹 서버)      │├─────────────────────────────────┤│  - syscalls.s (시스템콜 래퍼)     ││  - http.s (HTTP 파싱)           ││  - socket.s (소켓 통신)         │└─────────────────────────────────┘

핵심은 세 시스템콜이다. socket()으로 소캣을 생성하고, bind()로 포트를 할당하고, listen()으로 연결을 기다린다. 그리고 accept()로 클라이언트 연결을 수락한 후 read()/write()로 HTTP 요청/응답을 처리한다.

핵심 동작 원리

소켓 생성에서 요청 처리까지

AArch64 어셈블리에서 syscalls는 숫자로 호출된다. macOS ARM64에서상용적 syscall 번호는 다음과 같다.

socket: 97 (AF_INET = 2, SOCK_STREAM = 1)

bind: 104

listen: 106

accept: 30 (ARM64 macOS)

read: 3

write: 4

exit: 1

ARM64에서는 함수 호출 규약으로 x0~x7 레지스터를 인자 전달에 사용한다. x0에는 syscall 번호, x1~x7에는 인자가 들어간다.

// socket() 시스템콜 예시mov x0, 2          // AF_INETmov x1, 1          // SOCK_STREAMmov x2, 0          // protocolmov x16, 97        // socket syscall numbersvc 0x80           // 시스템콜 실행// 반환값은 x0에 저장 (음수면 에러)

HTTP 요청을 파싱할 때는 읽어들인 바이트에서 \r\n\r\n 시퀀스를 찾으면 헤더의 끝을 알 수 있다. 응답은 간단한 문자열 포맷으로 구성한다.

내 삶에 의미(부족)를 주기 위해 aarch64 어셈블리로 웹 서버 만들기
// HTTP 200 OK 응답 예시 (어셈블리 문자열).ascii "HTTP/1.1 200 OK\r\n".ascii "Content-Type: text/html\r\n".ascii "Content-Length: 13\r\n".ascii "Connection: close\r\n".ascii "\r\n".ascii "Hello, World!"

fork-per-connection 모델

ymawky는 연결마다 fork()를 호출하는 모델을 사용한다. 부모 프로세스는 listen() 상태로 새 연결을 기다리고, 자식 프로세스가 실제 요청을 처리한다.

// accept() 후 fork()mov x16, 2          // fork syscallsvc 0x80cmp x0, 0b.eq child_process  // if x0 == 0: child// parent closes client fd, continues listeningmov x0, client_fdmov x16, 6          // closesvc 0x80b accept_loop

ARM64에서 fork()는 매개변수 없이 syscall 번자 2만 전달하면 된다. 반환값으로 0을 받으면 현재 프로세스가 자식이고,푸라스치오받으면 부모이다.

실전 예제: ymawky 구조 분석

GitHub에서 확인할 수 있는 ymawky 프로젝트의 핵심은 3개 파일로구성된다.

1. server.s: 메인 루프 — socket/bind/listen/accept

2. request.s: HTTP 요청 파싱 및 응답 생성

3. fork.s: 프로세스 포크 및 자식 프로세스 핸들링

실제로 돌려보면 아주 단순한 HTTP 응답만 가능하지만, 그 단순함 자체가 교육적이다. 우리가 너무 많은 것을 당연하게 여기는 것을 깨닫게 해준다.

# 빌드 및 실행git clone https://github.com/imtomt/ymawkycd ymawkymake./ymawky 8080# 브라우저에서 http://localhost:8080 접속# "Hello, World!" 확인

대안과의 비교

어셈블리 웹 서버를 실제 프로덕션에 쓰지는 않는다. 그러나 공부용으로는 최고의 선택이다. 다른 언어와 비교하면 다음과 같다.

언어장점한계
어셈블리컴퓨터 동작 완전 이해, syscall 직접 호출개발 속도 느림, 이식성 낮음
C어셈블리에 가까운 성능, 이식성 양호메모리 관리 직접 해야 함
Gogoroutine으로 동시성 자연 처리, 빠른 개발런타임 의존성 존재
Rust메모리 안전성 보장,고성능학습 곡선 가파름

어셈블리로 웹 서버를 만들면 다른 언어가 어떤 추상화를 제공하는지 정확히 이해할 수 있다. Go의 http.ListenAndServe가 내부적으로는 똑같은 socket/bind/listen/accept를 호출한다는 사실을 체감하게 된다.

결론: 의미는 만드는 것이다

완벽한 웹 서버가 아니어도 괜찮다. 실제로 동작하는 것만으로도 충분한 만족감이 있다. 어셈블리로 작성한 웹 서버가 채급타적 "의미"가 된다.

"왜 굳이?"라는 질문에는 단 하나로 대답한다. 컴퓨터가 어떻게동쿠카진실으로 알고 싶었기 때문이다. 프레임워크의 추상화에 묻히지 않고, CPU와 메모리와 syscall의 세계로 직접강리테이쿠 때 비로소 개발자는 컴퓨터의lingua franca를 읽는 것이 된다.

ARM64 어셈블리로 웹 서버를 만드는 이 여정은, 의미는 찾는 게 아니라 직접 만드는 것이라는 사실을 보여준다.


📚 출처

GitHub - imtomt/ymawky: MacOS Web Server written entirely in ARM64 assembly

Building a Web Server in Pure ARM64 Assembly

Writing a Webserver in ARM64 Assembly - blog.nkoll.de

HTTP Server in arm64 assembly Apple silicon M1 - Medium

tags: ARM64, AArch64, Assembly, WebServer, LowLevel, syscall, macOS, developer


📚 출처

https://news.hada.io/topic?id=29335