Skip to content

Instantly share code, notes, and snippets.

@DGivney
Created May 2, 2019 02:11
Show Gist options
  • Star 11 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save DGivney/7196bd7a9f21a12c9397bdcf9ae040d2 to your computer and use it in GitHub Desktop.
Save DGivney/7196bd7a9f21a12c9397bdcf9ae040d2 to your computer and use it in GitHub Desktop.
NASM socket programming example
; Socket
; Compile with: nasm -f elf socket.asm
; Link with (64 bit systems require elf_i386 option): ld -m elf_i386 socket.o -o socket
; Run with: ./socket
%include 'functions.asm'
SECTION .data
; our response string
response db 'HTTP/1.1 200 OK', 0Dh, 0Ah, 'Content-Type: text/html', 0Dh, 0Ah, 'Content-Length: 14', 0Dh, 0Ah, 0Dh, 0Ah, 'Hello World!', 0Dh, 0Ah, 0h
SECTION .bss
buffer resb 255, ; variable to store request headers
SECTION .text
global _start
_start:
xor eax, eax ; init eax 0
xor ebx, ebx ; init ebx 0
xor edi, edi ; init edi 0
xor esi, esi ; init esi 0
_socket:
push byte 6 ; push 6 onto the stack (IPPROTO_TCP)
push byte 1 ; push 1 onto the stack (SOCK_STREAM)
push byte 2 ; push 2 onto the stack (PF_INET)
mov ecx, esp ; move address of arguments into ecx
mov ebx, 1 ; invoke subroutine SOCKET (1)
mov eax, 102 ; invoke SYS_SOCKETCALL (kernel opcode 102)
int 80h ; call the kernel
_bind:
mov edi, eax ; move return value of SYS_SOCKETCALL into edi (file descriptor for new socket, or -1 on error)
push dword 0x00000000 ; move 0 dec onto the stack IP ADDRESS
push word 0x2923 ; move 9001 dec onto stack PORT
push word 2 ; move 2 dec onto stack AF_INET
mov ecx, esp ; move address of stack pointer into ecx
push byte 16 ; move 16 dec onto stack (arguments length)
push ecx ; push the address of arguments onto stack
push edi ; push the file descriptor onto stack
mov ecx, esp ; move address of arguments into ecx
mov ebx, 2 ; invoke subroutine BIND (2)
mov eax, 102 ; invoke SYS_SOCKETCALL (kernel opcode 102)
int 80h ; call the kernel
_listen:
push byte 1 ; move 1 onto stack (max queue length argument)
push edi ; push the file descriptor onto stack
mov ecx, esp ; move address of arguments into ecx
mov ebx, 4 ; invoke subroutine LISTEN (4)
mov eax, 102 ; invoke SYS_SOCKETCALL (kernel opcode 102)
int 80h ; call the kernel
_accept:
push byte 0 ; push 0 dec onto stack (address length argument)
push byte 0 ; push 0 dec onto stack (address argument)
push edi ; push the file descriptor onto stack
mov ecx, esp ; move address of arguments into ecx
mov ebx, 5 ; invoke subroutine ACCEPT (5)
mov eax, 102 ; invoke SYS_SOCKETCALL (kernel opcode 102)
int 80h ; call the kernel
_fork:
mov esi, eax ; move return value of SYS_SOCKETCALL into esi (file descriptor for accepted socket, or -1 on error)
mov eax, 2 ; invoke SYS_FORK (kernel opcode 2)
int 80h ; call the kernel
cmp eax, 0 ; if return value of SYS_FORK in eax is zero we are in the child process
jz _read ; jmp in child process to _read
jmp _accept ; jmp in parent process to _accept
_read:
mov edx, 255 ; number of bytes to read (we will only read the first 255 bytes for simplicity)
mov ecx, buffer ; move the memory address of our buffer variable into ecx
mov ebx, esi ; move esi into ebx (accepted socket file descriptor)
mov eax, 3 ; invoke SYS_READ (kernel opcode 3)
int 80h ; call the kernel
mov eax, buffer ; move the memory address of our buffer variable into eax for printing
call sprintLF ; call our string printing function
_write:
mov edx, 78 ; move 78 dec into edx (length in bytes to write)
mov ecx, response ; move address of our response variable into ecx
mov ebx, esi ; move file descriptor into ebx (accepted socket id)
mov eax, 4 ; invoke SYS_WRITE (kernel opcode 4)
int 80h ; call the kernel
_close:
mov ebx, esi ; move esi into ebx (accepted socket file descriptor)
mov eax, 6 ; invoke SYS_CLOSE (kernel opcode 6)
int 80h ; call the kernel
_exit:
call quit ; call our quit function
@DGivney
Copy link
Author

DGivney commented Jul 11, 2021

Hey richllittle

Please see this comment for reference on functions.asm: DGivney/assemblytutorials#18 (comment)

The master branch has been updated with the namespaced file from the beginning.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment