; Just a little module to generate a linked list in memory and print ; it backwards to the console. ; ; George Cross, Borland C++ Tech Support, October 1998 ; ; Written for Borland Tasm 5.2b which comes with C++Builder. This ; code was adpated from that page 110 of the TASM Programmer's Guide, ; from Tasm 5.0. ; ; We use /ap to the linker to make the .exe open a console ; ; In the least, if writing an assembly program and not using any startup ; code, you must have something allocated in the data segment and you ; must import at least one Windows API function. ; ; ILink32 causes the error about missing __turboFloat and __setargv__ so ; you need to add dummy versions. TLink32 doesn't have this problem. ; ; ILink32 doesn't handle the assembler 'org' directive properly at this ; time. It should be fixed soon, but you must use Tlink32 for the time ; being instead. ; .386 model flat nosmart locals extern GetStdHandle:PROC extern WriteFile:PROC extern ExitProcess:PROC STD_OUTPUT_HANDLE = -11 EL_DATA_SIZE = 28 .data last_el_name equ <> first_el dd 0 ends ; structure defining elements of the list e struct data db EL_DATA_SIZE-2 dup (?) db 0dh,0ah next_el dd 0 e ends ; macro used to generate elements of the list makelist macro new_data:req new_data e <'&new_data'> ifidni last_el_name,<> org first_el dd new_data else org last_el_name + EL_DATA_SIZE dd new_data endif org new_data + size e last_el_name equ <&new_data> endm .data ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; Here we generate the linked list. Notice how our macro ; allows us to to make the nodes of the list non-contiguous in ; memory ; makelist Jeremy hConsole dd 0 makelist Anthony makelist Joshua x dd ? makelist Jodell makelist Sean makelist Shane makelist Caleb makelist McKenna makelist Pamela makelist Jason makelist Jacob makelist Ana makelist Anne .code ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; module_entry ; - module main entry point. module_entry: push STD_OUTPUT_HANDLE call GetStdHandle ; console handle in eax mov hConsole,eax call PrintListReverse call PrintList push 0 call ExitProcess ret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; PrintListReverse - ; - traverses the linked list reversing the pointers, then ; turns around printing the data of each node and flipping ; the pointers back. ; PrintListReverse proc cmp first_el,0 jz Finished_PrintListReverse ; traverse the linked list reversing the pointers mov eax,first_el mov ebx,[eax+EL_DATA_SIZE] mov first_el,0 cmp ebx,0 ; handle list of just one element jz @@3 @@1: mov edx,first_el mov [eax+EL_DATA_SIZE],edx mov first_el,eax mov eax,ebx mov ebx,[ebx+EL_DATA_SIZE] cmp ebx,0 jnz @@1 ; print the last element mov esi,EL_DATA_SIZE call PrintString ; traverse the linked list reversing the pointers and printing the ; data in each element @@2: mov ebx,eax mov eax,first_el mov edx,[eax+EL_DATA_SIZE] mov first_el,edx mov [eax+EL_DATA_SIZE],ebx @@3: call PrintString cmp first_el,0 jnz @@2 mov first_el,eax Finished_PrintListReverse: ret endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; PrintList ; - traverses the list printing each element along the way ; PrintList proc cmp first_el,0 jz Finished_PrintList mov eax,first_el mov esi,EL_DATA_SIZE @@1: call PrintString mov eax,[eax+EL_DATA_SIZE] cmp eax,0 jnz @@1 Finished_PrintList: ret endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; PrintString ; - function to print the given string to the console ; ; Input ; eax - address of string to print ; esi - length of string ; PrintString proc push ebp ; set up standard stack frame mov ebp,esp push eax ; WriteFile might clobber these push esi sub esp,4 ; local data push 0 lea edx,[ebp-0ch] push edx push esi push eax push hConsole call WriteFile add esp,4 pop esi pop eax pop ebp ret endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; Dummy publics to satify ILink32 ; .data public __turboFloat __turboFloat dd ? .code public __setargv__ label __setargv__ ret end module_entry