; ========================= SOURCE
FILE: _list2bin.asm =======================
; PURPOSE:
; Converts a Visual Prolog list (of many
possible list-domains) into an array
; of element-pointers (and vice-versa), in the
form of a Visual Prolog binary.
;
; APPLICATIONS:
; Large-scale fast Data Mining Applications
and/or very fast List Processing.
;
; ASSEMBLY LANGUAGE CODE begins here:
IDEAL ; Use TASM Assembler, version 5.*, "ideal mode" syntax
P586 ; Use Pentium-specific instructions
MODEL FLAT ; Use Flat memory model (accessing all hardware-RAM)
CODESEG ;
Code-segment follows
ALIGN 4
; 4-byte (dword-)alignment,
always required by Visual Prolog
; **************** ASSEMBLY LANGUAGE PUBLIC
PROCEDURES: *********************
public _list2bin_0 ; (i,i)
public _list2bin_1 ; (i,o)
public _list2bin_2 ; (o,i)
extrn _MEM_MakeBinaryGStack:near
extrn _MEM_AllocGStack:near
PROC _list2bin_0 near
; -(i,i)
mov ecx,[esp+4] ;
list_pointer in ECX
mov edx,[esp+8] ;
binary_pointer in EDX
push ebx ;
push edi ;
mov edi,4
; let EDI = 4
mov ah,2
; let AH = 2 (end_element_flag)
@@P1:
mov al,[byte
ptr ecx]
; load list_element_flag in AL
cmp al,ah
; is it an end-element?
jz @@X1
; if so, skip next...
; -------------------------------
mov ebx,[ecx+edi] ; load actual element into EBX
mov [edx],ebx
; write it to the output
mov ecx,[ecx+8] ;
make ECX = next_element_pointer
add edx,edi ; advance target_pointer
jmp short
@@P1 ; repeat the loop
; ===============================
@@X1: pop edi
pop ebx
retn
ENDP _list2bin_0
PROC _list2bin_1 near
; -(i,o)
mov ecx,[esp+4] ;
let ECX = list_pointer
mov edx,[esp+8] ;
binary_pointer in EDX
push edx ;
xor edx,edx ; initialize EDX as number-of-elements counter
push ecx ; save ECX
in the stack
mov ah,2
; prepare AH = 2 (end-element flag)
@@p1:
mov al,[byte
ptr ecx]
; put the "element-type indicator" in AL
cmp al,ah
; compare with 2 (end-of-list indicator)
jz @@p2
; if end of list, then exit!
; -------------------
inc edx ; else,
increment element_counter EDX
mov ecx,[ecx+8] ; make ECX = next list-element-pointer
jmp short
@@p1 ; repeat the
loopENDP _list2bin_1
; ===========================
@@p2: shl
edx,1 ;
shl edx,1
; now EDX = size of bytes
required (in binary)
push esi
;
push edi
;
push edx ;
call
_MEM_MakeBinaryGStack ; allocate memory for the
binary
pop edx ;
pop edi ;
pop esi ;
pop ecx
; restore ECX =
list_pointer (again!)
mov edx,eax ; let EDX = pointer to the new binary
push eax ;
push ebx ;
push edi ;
mov edi,4
; let EDI = 4
mov ah,2
; let AH = 2 (end_element_flag)
@@Q1: mov al,[byte
ptr ecx]
; load list_element_flag in AL
cmp al,ah
; is it an end-element?
jz @@X2
; if so, skip next...
; -----------------------
mov ebx,[ecx+edi] ; load actual element into EBX
mov [edx],ebx
; write it to the output
mov ecx,[ecx+8] ;
make ECX = next_element_pointer
add edx,edi ; advance target_pointer
jmp short
@@Q1 ; repeat the loop
; =======================
@@X2: pop edi ;
pop ebx
;
pop eax
;
pop edx
; restore arg2
mov [edx],eax
; make output_arg2 = binary
retn
ENDP _list2bin_1
PROC _list2bin_2 near
; -(o,i)
mov ecx,[esp+4] ;
let ECX = list_pointer
mov edx,[esp+8] ;
binary_pointer in EDX
push ECX ;
push ESI ;
push EDI ;
push ebx ;
push edx
;
mov ebx,4
;
mov eax,[edx-4] ; read binary_length
sub eax,ebx ;
shr eax,1
; now EAX = 2 * number of
list_elements
mov edx,eax ;
shr eax,1
; now EAX = number of
4-byte elements
push eax
; save it !
add eax,edx ; now EAX = 3 * number of list_elements
shl eax,1
; now EAX = 6 * number of
list_elements
shl eax,1
; now EAX = 12 * number of
list_elements
add eax,12
; + 12 more elements (for "end_element"
in list)
push eax ;
call
_MEM_AllocGStack ; allocate memory for the
dword_List
pop ecx ;
pop ecx ; restore
number of elements into ECX
mov edi,eax ; now EDI = start of new List_object
pop esi ; restore
ARG2 (binary), but into ESI
push eax
; save the "new list" also in the stack
mov ebx,4
; make ebx = 4
@@p1:
mov
eax,1 ; make
eax = 1 (normal list element flag)
stosd
; write "normal list_element flag" to
EDI, EDI->EDI+4
movsd
; move 4 bytes, advance both ESI and
EDI by 4
mov eax,edi ;
add eax,ebx ; EAX := ptr to "next list element" on target EDI
stosd
; write it, advancing EDI by 4,
dec ecx ; decrement counter
jnz @@p1
; repeat loop, if ECX > 0
; -----------------------
@@p2: mov
eax,2 ;
stosd
; write an "end of list flag" into EDI,
EDI -> EDI+4
xor eax,eax ;
stosd
;
stosd
; write 8 dummy bytes to last
list-element
pop eax ; recover new_list_start_pointer, into EAX
pop ebx
;
pop edi
;
pop esi
;
pop ecx
;
mov [ecx],eax
; make output_arg2 = number_list
retn
ENDP _list2bin_2
end ; End of all ASM code. (Anything below this point is
ignored by TASM)
/************************* VISUAL PROLOG test-program:
**********************/
GLOBAL DOMAINS
ILIST = INTEGER*
SLIST = INTEGER*
GLOBAL PREDICATES
list2bin(ILIST,BINARY) -(i,i),(i,o),(o,i) language
c
slist2bin(SLIST,BINARY) -(i,i) language c as "_list2bin_0"
slist2binx(SLIST,BINARY) -(i,o) language c as "_list2bin_1"
slistx2bin(SLIST,BINARY) -(o,i) language c as "_list2bin_2"
nondeterm repeat % defined elsewhere
GOAL
getbacktrack(TEST1),
repeat,
write("give an
integer-list:\n> "), readln(S), term_str(ilist,ILx,S),
Len = length(ILx), Bin =
makebinary(Len,4),
write("First,
creating a new binary: ",Bin), nl, list2bin(ILx,Bin),
write("this
existing binary became: ",Bin), nl, list2bin(ILx,Binx1),
SZx1 = getbinarysize(Binx1), write("binary size = ",SZx1), nl,
write("and a new
'fresh' binary is: ",Binx1), nl, list2bin(IL2x,Binx1),
write("converting
the binary back into a list: ",IL2x),
write("\nPress ESC
to exit, any other key for the next test...\n"),
readchar(C1x),
C1x='\27',
cutbacktrack(TEST1),
getbacktrack(TEST2),
repeat,
write("give a
string-list:\n> "), readln(S2), term_str(slist,SLx,S2),
slist2binx(SLx,BNSx), SZx = getbinarysize(BNSx), write("binary size = ",SZx), nl,
write("Binary with
string-pointers: ",BNSx),
readchar(_), slistx2bin(SLx2,BNSx),
write("\nNew list
generated from this binary:\n",SLx2), nl,
write("\nPress ESC
to exit, any other key to repeat...\n"),
readchar(C2x),
C2x='\27',
cutbacktrack(TEST2),
!.
; ************** "32-bit Assembly Language
Extensions for Visual Prolog" ****************
; Written by George A. Stathis (c) 2005,
E-mail: omadeon@yahoo.com,
gstathis@enm.gr
; URL: http://www.omadeon.com/asm
Company: ENB Ltd. Company
site: http://www.enb.gr
; **** Use of this source-code is unrestricted
provided that the author is mentioned. ****