I wrote a stack implementation using a singly linked list in x86_64 assembly. This stack supports the usual push
/pop
operations as well as first/next for iterating over each element.
I'm looking for general feedback.
Here are the stack subroutines:
; Stack Structure
; Pointer Head
; Pointer Current
; Stack Node
; Pointer Next
; Pointer Value
; input
; void
; output
; stack or 0 on error
StackCreate:
mov rdi, 24
call malloc
test rax,rax
jz StackCreate_end
xor rdi, rdi
mov [rax], rdi
mov [rax+8], rdi
ret
StackCreate_end:
add rsp, 8
ret
; input
; stack
; output
; void
StackDestroy:
call free
ret
; input
; stack
; value
; output
; 0 on error
StackPush:
push rdi
push rsi
mov rdi, 16
call malloc
test rax,rax
jz StackPush_end
pop rsi
pop rdi
mov rdx, [rdi]
mov [rax], rdx
mov [rax+8], rsi
mov [rdi], rax
ret
StackPush_end:
add rsp, 16
ret
; input
; stack
; output
; value or 0 if empty
StackPop:
mov rsi, rdi
mov rdi, [rdi]
test rdi, rdi
jz StackPop_end
mov rax, [rdi]
mov [rsi], rax
mov rax, [rdi+8]
push rax
call free
pop rax
ret
StackPop_end:
xor rax, rax
ret
nop;e
; input
; stack
; output
; value or 0 if empty
StackFirst:
mov rax, [rdi]
test rax, rax
jz StackFirst_end
mov rsi, [rax]
mov [rdi+8], rsi
mov rax, [rax+8]
StackFirst_end:
ret
; input
; stack
; output
; value or 0 if end
StackNext:
mov rsi, [rdi+8]
test rsi, rsi
jz StackNext_end
mov rax, [rsi]
mov [rdi+8], rax
mov rax, [rsi+8]
ret
StackNext_end:
xor rax, rax
ret
Here is a driver:
[extern puts]
[extern malloc]
[extern free]
[SECTION .data]
arguments:
db "Incorrect arguments.",10,"Expected: stackme <string1> <string2> ...",0
[SECTION .text]
BITS 64
global main
wrong_arguments:
mov rdi, arguments
call puts
jmp main_end
main:
cmp rdi, 1
jle wrong_arguments
lea r12, [rsi+8]
lea r13, [rdi-1]
call StackCreate
test rax, rax
jz main_end
mov r14, rax
pushing_loop:
test r13, r13
jz pushing_done
mov rdi, r14
mov rsi, [r12]
call StackPush
add r12, 8
dec r13
jmp pushing_loop
pushing_done:
mov rdi, r14
call StackFirst
print_loop:
test rax, rax
jz print_done
mov rdi, rax
call puts
mov rdi, r14
call StackNext
jmp print_loop
print_done:
stack_delete:
mov rdi, r14
call StackPop
test rax, rax
jnz stack_delete
stack_delete_done:
mov rdi, r14
call StackDestroy
main_end:
xor eax, eax
ret
Assembling/Linking
nasm -f elf64 -l stackme.lst stackme.asm
gcc -o stackme stackme.o