Module 1:
;*******************************************************************************
; A generic Linked List ADT for any datatype.
;
; Author: William
.386
.MODEL flat, stdcall
.STACK 4096
PUBLIC push_front, print_list
; Win32 function prototypes and synonyms
GetProcessHeap PROTO
HeapAlloc PROTO, hHeap:DWORD,
dwFlags:DWORD,
dwBytes:DWORD
GetStdHandle PROTO, nStdHandle:DWORD
WriteConsoleA PROTO, hConsoleOutput:DWORD,
lpBuffer:PTR DWORD,
nNumberofCharsToWrite:DWORD,
lpNumberOfCharsWritten:PTR DWORD,
lpReserved:DWORD
STD_OUTPUT_HANDLE equ -11
HEAP_ZERO_MEMORY equ 00000008h
.CODE
;-------------------------------------------------------------------------------
; print_list(hptr, fptr)
;
; Prints nodes of given linked list
;
; Entry:
hptr EQU [ebp + 8] ;head ptr
fptr EQU DWORD PTR[ebp + 12] ;std_call func ptr that
; prints list data type
;-------------------------------------------------------------------------------
print_list:
push ebp
mov ebp, esp
sub esp, 12
push eax
push edx
push ebx
; Locals variables
arrow EQU [ebp - 4] ;string "-> "
mov DWORD PTR arrow, ' >-'
nstr EQU [ebp - 8] ;string "NULL"
mov DWORD PTR nstr, 'LLUN'
wrtn EQU [ebp - 12] ;num of chars written
mov DWORD PTR wrtn, 0
; loop while(node != NULL)
mov ebx, hptr
jmp endL3
L3:
; print (node->data)
push [ebx]
call fptr
; print "-> "
INVOKE GetStdHandle,
STD_OUTPUT_HANDLE
mov edx, eax
INVOKE WriteConsoleA, edx,
ADDR arrow,
3,
ADDR wrtn,
0
;node = node -> next
mov ebx, [ebx + 4]
endL3: test ebx, ebx
jnz L3
;print "NULL"
INVOKE GetStdHandle,
STD_OUTPUT_HANDLE
mov edx, eax
INVOKE WriteConsoleA, edx,
ADDR nstr,
4,
ADDR wrtn,
0
pop ebx
pop edx
pop eax
mov esp, ebp
pop ebp
ret 8
;-------------------------------------------------------------------------------
; push_front(headptr, dataptr, dsiz)
;
; Adds a new linked list node to the front of a linked list.
;
; Entry:
hptr EQU [ebp + 8] ;DW ptr to headptr
dptr EQU [ebp + 12] ;DW data ptr
dsiz EQU [ebp + 16] ;DW data size in bytes
node_size EQU 00000008h
;-------------------------------------------------------------------------------
push_front:
; set up stack save regs
push ebp
mov ebp, esp
push eax
push ebx
push ecx
push edx
push esi
; allocate memory for new node
call GetProcessHeap
INVOKE HeapAlloc, eax,
HEAP_ZERO_MEMORY,
node_size
mov ebx, eax ;save node in ebx
; allocate memory for new data
call GetProcessHeap
INVOKE HeapAlloc, eax,
HEAP_ZERO_MEMORY,
dsiz
; save into new node
mov [ebx], eax ;node->data = new data
mov eax, hptr
mov eax, [eax] ;dereference hptr
mov [ebx + 4], eax ;node->next = hptr
; loop copying data into newly allocated
; memory byte per byte
mov edx, dsiz
mov esi, dptr
xor ecx, ecx ;loop counter
jmp endL1
L1: mov al, [esi + ecx]
mov [ebx + ecx], al
inc ecx
endL1: cmp ecx, edx
jl L1
; hptr = new node
mov eax, hptr
mov [eax], ebx
; restore regs clean up stack
pop esi
pop edx
pop ecx
pop ebx
pop eax
pop ebp
ret 12
END
Module 2
;*******************************************************************************
; LL_main.asm is the main module that demonstrates the Linked_List ADT
;
; Author: William
.386
.MODEL flat, stdcall
.STACK 4096
EXTERN push_front:near,
print_list:near
; Win32 API function prototypes and synonyms
ExitProcess PROTO, dwExitCode:DWORD
GetStdHandle PROTO, nStdHandle:DWORD
WriteConsoleA PROTO, hConsoleOutput:DWORD,
lpBuffer:PTR DWORD,
nNumberofCharsToWrite:DWORD,
lpNumberOfCharsWritten:PTR DWORD,
lpReserved:DWORD
STD_OUTPUT_HANDLE EQU -11
NULL EQU 0
.CODE
;-------------------------------------------------------------------------------
; print_hex(num)
;
; prints a 32 bit unsigned hexadecimal number to the console
;
; Entry:
num EQU [ebp + 8] ; DW unsigned hex number
;-------------------------------------------------------------------------------
print_hex:
; set up stack frame, save regs
push ebp
mov ebp, esp
sub esp, 4
push eax
push ebx
push edx
push esi
; local variable for # of chars written by WriteConsoleA
nWrtn EQU [ebp - 4]
mov DWORD PTR nWrtn, 0
; This loop repeatedly divides the number by 10h, converts the remainder
; to its corresponding ASCII code, and then saves the char to the stack
mov eax, num
mov ebx, 10h ; the divisor, 10h
xor edx, edx ; clear edx
xor esi, esi ; esi = num of chars
L1: div ebx ; div num by 10h
;convert remainer to ASCII code
;if edx > 9, add 7
cmp edx, 9
jle endIf1
add edx, 7
endIf1:
;add char '0' to num
add edx, '0'
;put char on stack
dec esp ; allocate stack space
mov [esp], dl ; save char to stack
inc esi ; inc num of chars
xor edx, edx ; clear edx
; end of loop L1
test eax, eax ; loop while num != 0
jnz L1
; print out chars from the stack
mov edx, esp
INVOKE GetStdHandle, STD_OUTPUT_HANDLE
mov ecx, eax
INVOKE WriteConsoleA, ecx,
edx,
esi,
ADDR nWrtn,
NULL
add esp, esi ; restore esp ;
;clean up stack, restore regs
pop esi
pop edx
pop ebx
pop eax
mov esp, ebp
pop ebp
ret 4
;-------------------------------------------------------------------------------
; main()
;
; creates a linked list of integers and prints them to the screen.
;-------------------------------------------------------------------------------
main:
mov ebp, esp
sub esp, 8
; local variables
head_ptr EQU [ebp - 4] ; head of list
mov DWORD PTR head_ptr, 0
hex_int EQU [ebp - 8] ; a starting int
mov DWORD PTR hex_int, 10fd134h
; loop L2 adds 6 numbers to list
xor esi, esi ; loop counter
L2:
; add hex_int to front of the list
push 4
lea eax, hex_int
push eax
lea eax, head_ptr
push eax
call push_front
inc esi
add DWORD PTR hex_int, 14768h
; end of L2
cmp esi, 6 ; while (esi < 6)
jl L2
; print out list
push print_hex
push head_ptr
call print_list
mov esp, ebp
INVOKE ExitProcess, 0
END main
Output:
116363C-> 114EED4-> 113A76C-> 1126004-> 111189C-> 10FD134-> NULL
This is a minimal implementation of a Linked List that took me a long time to figure out and get working. It only allows you to create a list, push to it, and print it out. There is no way to destroy the list, so the program leaks memory.
I'm looking for ALL criticism.