Http Server in Assembly Language

Here’s the translation of the HTTP server example from Go to Assembly Language, formatted in Markdown suitable for Hugo:

; Writing a basic HTTP server in assembly language is considerably more complex
; than in high-level languages. This example provides a simplified demonstration
; using x86 assembly for Linux.

section .data
    hello_msg db 'HTTP/1.1 200 OK', 13, 10
              db 'Content-Type: text/plain', 13, 10
              db 'Content-Length: 7', 13, 10
              db 13, 10
              db 'hello', 13, 10, 0
    hello_len equ $ - hello_msg

section .text
    global _start

_start:
    ; Create socket
    mov eax, 41          ; socket system call
    mov ebx, 2           ; AF_INET
    mov ecx, 1           ; SOCK_STREAM
    mov edx, 0           ; protocol
    int 0x80
    mov esi, eax         ; save socket descriptor

    ; Bind to port 8090
    push dword 0         ; INADDR_ANY
    push word 0x821f     ; port 8090 (network byte order)
    push word 2          ; AF_INET
    mov ecx, esp         ; pointer to struct sockaddr
    push 16              ; address length
    push ecx             ; struct sockaddr *
    push esi             ; socket descriptor
    mov eax, 49          ; bind system call
    mov ebx, esi
    mov ecx, esp
    mov edx, 16
    int 0x80

    ; Listen for connections
    push 1               ; backlog
    push esi             ; socket descriptor
    mov eax, 50          ; listen system call
    mov ebx, esi
    mov ecx, 1
    int 0x80

    ; Accept connections
accept_loop:
    push 0               ; addr_len
    push 0               ; struct sockaddr *addr
    push esi             ; socket descriptor
    mov eax, 43          ; accept system call
    mov ebx, esi
    mov ecx, 0
    mov edx, 0
    int 0x80
    mov edi, eax         ; save client socket descriptor

    ; Send response
    push hello_len       ; message length
    push hello_msg       ; message
    push edi             ; client socket descriptor
    mov eax, 4           ; write system call
    mov ebx, edi
    mov ecx, hello_msg
    mov edx, hello_len
    int 0x80

    ; Close client socket
    mov eax, 6           ; close system call
    mov ebx, edi
    int 0x80

    jmp accept_loop      ; continue accepting connections

    ; Exit (unreachable in this example)
    mov eax, 1           ; exit system call
    xor ebx, ebx
    int 0x80

This assembly language example provides a basic HTTP server that listens on port 8090 and responds with a “hello” message to all requests. Here’s an explanation of the code:

  1. We define the response message in the .data section, including HTTP headers and the “hello” body.

  2. In the _start function, we create a socket using the socket system call.

  3. We bind the socket to port 8090 using the bind system call.

  4. The server starts listening for connections with the listen system call.

  5. We enter an infinite loop (accept_loop) to accept incoming connections using the accept system call.

  6. For each accepted connection, we send the pre-defined response using the write system call.

  7. We close the client socket after sending the response.

  8. The server continues to accept new connections indefinitely.

To run this assembly program:

  1. Save the code in a file named http_server.asm.
  2. Assemble and link the program:
$ nasm -f elf http_server.asm
$ ld -m elf_i386 -o http_server http_server.o
  1. Run the server:
$ ./http_server

The server will now be listening on port 8090. You can test it using curl:

$ curl localhost:8090
hello

Note that this is a very basic implementation and lacks error handling and proper HTTP request parsing. In practice, writing a production-ready HTTP server in assembly language would be much more complex and is not recommended for most use cases.