Created
December 20, 2023 20:02
-
-
Save shivanshu3/3e71b42e37dc17a342b4e131e47f1242 to your computer and use it in GitHub Desktop.
Linked List Windows x86_64 Implementation in NASM assembly
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
; 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