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
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>"
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
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
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
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)