;
================== source-file: _repcount.asm ======================
COMMENT
~
Purpose:
Counters and FOR-loops in Assembly Language for Visual Prolog.
To
compile: - Use Turbo Assembler (TASM) version 5 or higher, with
the command-line: TASM32 /p /z /w2 /m2 /ml %1.asm
Author:
George A. Stathis (c) 2005.
(Permission
also granted to ENB Ltd,
for use of this code).
License:
All use of this code is permitted, without restrictions, provided that
the author is mentioned in
any applications making use of this code.
%%%%%%%%%%%%
Visual Prolog Global Declarations:
GLOBAL
PREDICATES
nondeterm
repcount(INTEGER initial_value,INTEGER out_value)
-(i,o) language c
nondeterm
repcount(INTEGER initialVal,INTEGER
finalVal,INTEGER outVal)
-(i,i,o) language c
~
;
=====================================================================
IDEAL
; Use IDEAL mode, in Turbo Assembler 5.*
P586
; Enable Pentium instructions
MODEL
FLAT ; Use Flat Memory Model (32-bit access)
CODESEG
; Code-segment starts here
ALIGN
4 ; Use 4-byte alignment
public
_repcount_0
public
_repcount_1
extrn
_RUN_Fail:near ; Visual
Prolog's "failure"
extrn
_RUN_StackBTrack:near ; Visual Prolog's "Stack BackTrack point"
extrn
_RUN_JmpReturn1:near ; Visual Prolog's "Return to Backtrack
pt"
;
=====================================================================
; Variant
which acts like a general-purpose counter in an endless loop:
;
=====================================================================
PROC _repcount_0
near
; repcount(Initial_value,OUT) -(i,o)
ENTER
8,0
ARG
minval:dword, outval:dword
LOCAL
prev:dword
mov edx,[minval] ; minimum value in EDX
as counter (ARG 1)
@@Lp0:
mov ecx,[outval] ; output
value
(ARG 2)
mov [ecx],edx ; produce
output
inc
edx
; increment counter EDX
mov [prev],edx ; store
resulting value in a local variable
call _RUN_StackBTrack ; stack a backtrack point in Visual Prolog
mov edx,[prev] ; restore the counter from the
local variable
or eax,eax ; check the
result of "RUN_StackBTrack"
jne @@Lp0 ; if
not zero, repeat!
;
-----------------------------
call _RUN_JmpReturn1 ; call Visual Prolog function 'JmpReturn'
LEAVE
ENDP
_repcount_0
;
======================================================================
; Variant
which acts like a "FOR-loop" between initial and final values:
;
======================================================================
PROC _repcount_1
near ; repcount(InitValue,MaxValue,OUT) -(i,i,o)
ENTER
8,0
ARG
minval:dword, maxval:dword, outval:dword
LOCAL
prev:dword
mov edx,[minval] ; minimum value in EDX as counter (ARG
1)
@@Lp0:
mov ecx,[outval] ; output
value
(ARG 3)
mov [ecx],edx ; produce output
inc edx ;
increment counter EDX
mov ecx,[maxval] ; maximum value in
ECX
(ARG 2)
cmp edx,ecx ; compare counter_value
to max_value
ja @@XX ;
if max_value exceeded, exit with failure!
;
-------------------------
mov [prev],edx ; store the resulting value in local
variable
call _RUN_StackBTrack ; stack a backtrack point in Visual Prolog
mov edx,[prev] ; restore the counter from the local
variable
or eax,eax ; check the result
of "RUN_StackBTrack"
jne @@Lp0 ; if not
zero, repeat!
;
----------------------------
call _RUN_JmpReturn1 ; call Visual Prolog function 'JmpReturn'
@@XX:
call _RUN_Fail ; call Visual
Prolog's "fail"
LEAVE
ENDP
_repcount_1
END
;
================ VISUAL PROLOG TEST-PROGRAM: =================
%USAGE:
Compile the following as an "EASYWIN" project:
GLOBAL
PREDICATES
nondeterm repcount(INTEGER
init_value,INTEGER out_value)
-(i,o) language c
PREDICATES
test(INTEGER)
CLAUSES
test(1):- repcount(1,X),
random(100,Num), write(X,"th random number: ",Num), nl,
write("PRESS ESCAPE to EXIT, any other key to go on!\n"),
readchar(CH), CH = '\27', !.
test(2):- repcount(1,10,X),
random(100,Num), write(X,"th random number: ",Num), nl, fail.
test(2).
GOAL
write("\nFirst, testing
repcount(Min,OUT) -(i,o):\n\n"),
test(1), write("\nNow a test for repcount(Min,Max,OUT):\n"),
test(2), readchar(_).