Skip to content

Instantly share code, notes, and snippets.

@shivanshu3
Created December 20, 2023 20:02
Show Gist options
  • Save shivanshu3/3e71b42e37dc17a342b4e131e47f1242 to your computer and use it in GitHub Desktop.
Save shivanshu3/3e71b42e37dc17a342b4e131e47f1242 to your computer and use it in GitHub Desktop.
Linked List Windows x86_64 Implementation in NASM assembly
; Build Instructions
; nasm -fwin64 -gcv8 LinkedListWin64.s
; link LinkedListWin64.s /entry:main_asm /subsystem:console /debug kernel32.lib ucrt.lib
bits 64
default rel
struc List
.head: resq 1
endstruc
struc Node
.data: resd 1
resd 1 ; Padding
.next: resq 1
endstruc
section .rdata
align 16
hello_world_str: db 'Hello, World!', 0
section .data
align 16
section .text
align 16
global ll_init
global ll_append
global ll_delete
global main_asm
extern malloc
extern free
extern puts
; In: List*
; Out: The new head Node ptr
align 16
ll_init:
push r12
sub rsp, 32
mov r12, rcx
mov rcx, Node_size
call malloc
mov dword [rax + Node.data], 0
mov qword [rax + Node.next], 0
mov qword [r12 + List.head], rax
add rsp, 32
pop r12
ret
; In: Ptr to Node head (rcx)
; Out: None
; Traverses the linked list to the end, and updates rcx
align 16
ll_traverse_end:
.loop:
cmp qword [rcx + Node.next], 0
jz .endloop
mov rcx, qword [rcx + Node.next]
jmp .loop
.endloop:
ret
; In1: Ptr to Node head (rcx)
; In2: Data (rdx)
; Out: None
; Traverses the linked list until it finds the node with the given data.
; rcx will be set to the node before the matching node.
; Or it will be set to 0 if no such node can be found.
; Or it will be set to 1 if it's the head node.
align 16
ll_find_data:
mov rax, 1
.loop:
cmp dword [rcx + Node.data], edx
jz .endloop_success
cmp qword [rcx + Node.next], 0
jz .endloop_fail
mov rax, rcx
mov rcx, qword [rcx + Node.next]
jmp .loop
.endloop_success:
mov rcx, rax
ret
.endloop_fail:
mov rcx, 0
ret
; In: Ptr to List
; Out: Ptr to new Node
align 16
ll_append:
push r12
sub rsp, 32
mov rcx, qword [rcx + List.head]
call ll_traverse_end
mov r12, rcx ; This is the last node
mov rcx, Node_size
call malloc
mov dword [rax + Node.data], 0
mov qword [rax + Node.next], 0
mov qword [r12 + Node.next], rax
add rsp, 32
pop r12
ret
; In1: Ptr to List
; In2: Data
; Out: None
; Finds the Node with the given data in the list and deletes it
align 16
ll_delete:
push r12
push r13
sub rsp, 40
mov r12, rcx
mov rcx, qword [r12 + List.head]
call ll_find_data
cmp rcx, 0
jz .exit
cmp rcx, 1
jz .delete_head
; Now we have the node which points to the node which needs to be deleted
; Let's repurpose r12 to point to the node to be deleted, and r13 to the node after that
; rcx -> r12 -> r13
mov r12, qword [rcx + Node.next]
mov r13, qword [r12 + Node.next]
; Connect rcx to r13
mov qword [rcx + Node.next], r13
; Free r12
mov rcx, r12
call free
jmp .exit
.delete_head:
mov rcx, qword [r12 + List.head]
mov r13, qword [rcx + Node.next]
call free
mov qword [r12 + List.head], r13
.exit:
add rsp, 40
pop r13
pop r12
ret
align 16
main_asm:
sub rsp, 40
lea rcx, [hello_world_str]
call puts
add rsp, 40
ret
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment