DEV Community

Cover image for I built a web server in assembly
Manan Sharma
Manan Sharma

Posted on

I built a web server in assembly

Hi everybodyđź‘‹

I spent yesterday night reading about the assembly language. I realized that assembly is a very powerful language, but it is really difficult to work with. Like, this is what it takes just to print a small text:

extern printf

section .data
    msg  db "Hello, world from x86-64 NASM!", 10, 0

section .text
    global main

main:
    sub rsp, 40            ; shadow space + alignment

    ; print msg
    lea rcx, [msg]
    call printf

Enter fullscreen mode Exit fullscreen mode

Still, this sparked my curiosity and I searched "Can I build a web server in assembly?". I had already built a server in C. But I wanted to remove the abstractions completely.

To build this server, I had to write the response format first, which looked like this:

response:
    db "HTTP/1.1 200 OK", 13, 10
    db "Content Type: text/html", 13, 10
    db "Content Length: 21", 13, 10
    db "Connection: close", 13, 10, 13, 10
    db "<h1>Hello there!</h1>"

Enter fullscreen mode Exit fullscreen mode

Then, declaring port address : dw 0x901F, which is port 8080.
The port has to be in network byte order (big-endian), and x86 is little-endian. So, 8080 in hex is 0x1F90; Network byte order means the bytes in memory must be 1F 90; and dw 0x901F stores the low byte first, so memory ends up as 1F 90, which is exactly what the network expects.

After port declaration, I had to call WSAStartup to start the Windows socket API, bind it to the port and listen to the request.

main:
    sub rsp, 40
    mov ecx, 0x0202
    lea rdx, [wsadata]
    call WSAStartup
    test eax, eax
    jnz fail

    mov ecx, 2
    mov edx, 1
    mov r8d, 6
    call socket
    cmp rax, -1
    je fail
    mov [listen_sock],  rax

    mov rcx, rax
    lea rdx, [addr]
    mov r8d, 16
    call bind
    test eax, eax
    jnz fail

    mov rcx, [listen_sock]
    mov edx, 128
    call listen
    test eax, eax
    jnz fail
Enter fullscreen mode Exit fullscreen mode

These listen, bind, recv, etc were calls into the dynamic link libraries. It is a format Windows uses to implement shared library concept.

At last, a simple call to ExitProcess to stop listening.

    mov ecx, 1
    call ExitProcess

Enter fullscreen mode Exit fullscreen mode

To run the server, first I need to build the object file, then an executable file.

;Build object file : nasm -f win64 server.asm -o server.obj
;Build executable : gcc server.obj -o server.exe -lws2_32
;Run the server : ./server.exe
Enter fullscreen mode Exit fullscreen mode

Overall, this was a fun thing to build. I learnt about DLL, how the instructions work, and how can I serve an external static file.

See the code here.

Top comments (0)