Microsoft (R) Macro Assembler Version 6.11                  02/13/01 12:10:54
sieve.asm                                                    Page 1 - 1


                                        PAGE    240,132
                                ; \SIEVE.XPL    MAY-19-95
                                ; \Eratosthenes Sieve Prime Number Program
                                ; 
                                ; code  CRLF=9, INTOUT=11, TEXT=12;
                                ; define        SIZE = 8190;
                                ; integer       PRIME, COUNT, ITER, I, K;
                                        INCLUDE RUNTIME.ASM
                              C ;RUNTIME.ASM    03-FEB-2001
                              C ;SYMBOLS THE COMPILIED XPL0 PROGRAM MUST KNOW ABOUT
                              C 
 0000                           CSEG    SEGMENT DWORD PUBLIC 'CODE'
                                        ASSUME CS:CSEG
 0000                           PROGRM:
 0000  83 C7 12                         ADD     DI,18           ;reserve space for variables
 0003  B8 1FFF                          MOV     AX,8191         ;reserve FLAGS array
 0006  50                               PUSH    AX
 0007  B8 0001                          MOV     AX,1            ;1-dimensional array
 000A  50                               PUSH    AX
                                                                ;ax = 1 = 1 byte per element
 000B  0E                               PUSH    CS
 000C  E8 0000 E                        CALL    NEAR PTR MKARRAY;set up pointer to array and
                                ; addr  FLAGS(SIZE+1);          ; reserve space in heap

                                ; 
                                ; begin

 000F  33 C0                            XOR     AX,AX           ;TEXT statement, device = 0
 0011  50                               PUSH    AX

 0000                           DSEG    SEGMENT WORD PUBLIC 'DATA'

 0000 31 30 30 30 20 69         L1      DB      "1000 iterations",13,""
       74 65 72 61 74 69
       6F 6E 73 0D 8A
 0012                           DSEG    ENDS

 0012  B8 0000 R                        MOV     AX,OFFSET L1    ;address of string
 0015  0E                               PUSH    CS
 0016  E8 0000 E                        CALL    NEAR PTR INTR12 ;TEXT intrinsic
                                ; TEXT(0, "1000 iterations
                                ; ");

 0019  C7 44 0C 0001                    MOV     WP [SI]+12,1    ;ITER
 001E  8B 54 0C                         MOV     DX,WP [SI]+12

 0021                           L2:
                                ; for ITER:= 1, 1000 do                         \do program 1000 times

                                ;       begin
 0021  33 C0                            XOR     AX,AX
 0023  89 44 0A                         MOV     WP [SI]+10,AX
                                ;       COUNT:= 0;                              \prime counter

                                        
 0026  89 44 0E                         MOV     WP [SI]+14,AX   ;zero is already in AX
 0029  92                               XCHG    DX,AX           ;DX shadows 'for' loop
                                                                ; control variable
 002A                           L3:
                                ;       for I:= 0, SIZE do

 002A  8B 5C 12                         MOV     BX,WP [SI]+18   ;FLAGS
 002D  03 DA                            ADD     BX,DX           ;+ I
 002F  42                               INC     DX
 0030  81 FA 1FFE                       CMP     DX,8190         ;SIZE (a constant)
 0034  C6 07 FF                         MOV     BYTE PTR [BX]+0,-1 ;delayed store (of 'true'
 0037  7E F1                            JLE     L3                 ; value) avoids AGI delay
 0039  89 54 0E                         MOV     WP [SI]+14,DX   ;make sure I = SIZE+1 (XPL feature)

                                ;               FLAGS(I):= true;                \set flags all true

 003C  33 C0                            XOR     AX,AX
 003E  89 44 0E                         MOV     WP [SI]+14,AX   ;I
 0041  92                               XCHG    DX,AX

 0042                           L4:
                                ;       for I:= 0, SIZE do

 0042  8B 5C 12                         MOV     BX,WP [SI]+18   ;FLAGS
 0045  03 DA                            ADD     BX,DX           ;+ I
 0047  8A 07                            MOV     AL,[BX]
 0049  32 E4                            XOR     AH,AH
                                        ORG     $-2             ;eliminate previous XOR
 0049  84 C0                            TEST    AL,AL
 004B  74 2E                            JE      L6
                                ;           if FLAGS(I) then                    \found a prime

                                ;               begin
 004D  8B C2                            MOV     AX,DX           ;I
 004F  03 C0                            ADD     AX,AX           ;+ I
 0051  83 C0 03                         ADD     AX,3            ;+ 3
 0054  89 44 08                         MOV     WP [SI]+8,AX    ;PRIME
                                ;               PRIME:= I +I +3;                \twice the index + 3

 0057  03 C2                            ADD     AX,DX           ;PRIME already in AX
 0059  89 44 10                         MOV     WP [SI]+16,AX   ;K
                                ;               K:= I + PRIME;                  \first multiple to kill


 005C                           L7:
 005C  8B 44 10                         MOV     AX,WP [SI]+16   ;can't assume AX=K because of L7:
 005F  3D 1FFE                          CMP     AX,8190         ;SIZE
 0062  B8 FFFF                          MOV     AX,-1           ;\
 0065  7E 01                            JLE     $+3             ;  \ eliminated
 0067  40                               INC     AX              ;  /
                                        ORG     $-6             ;/
 0062  7F 10                            JG      L9
                                ;               while K <= SIZE do

                                ;                       begin
 0064  8B 5C 12                         MOV     BX,WP [SI]+18   ;FLAGS
 0067  03 D8                            ADD     BX,AX           ;+ K  ('false' stored later)
                                ;                       FLAGS(K):= false;       \zero a non-prime
                                                                ;AX = K
 0069  03 44 08                         ADD     AX,WP [SI]+8    ;K + PRIME
 006C  89 44 10                         MOV     WP [SI]+16,AX   ;K
                                ;                       K:= K +PRIME;           \next multiple

 006F  C6 07 00                         MOV     BYTE PTR [BX]+0,0 ;store 'false' (AGI)
 0072  EB E8                            JMP     L7              ;end of 'while' loop

 0074                           L9:
                                ;                       end;

 0074  8B 44 0A                         MOV     AX,WP [SI]+10   ;INC WP [SI]+10 is harder than
 0077  40                               INC     AX              ; you'd think.  ('inc' operator?)
 0078  89 44 0A                         MOV     WP [SI]+10,AX
                                ;               COUNT:= COUNT +1;               \primes found


 007B                           L6:
 007B  42                               INC     DX              ;next I
 007C  81 FA 1FFE                       CMP     DX,8190         ;SIZE
 0080  7E C0                            JLE     L4
 0082  89 54 0E                         MOV     WP [SI]+14,DX   ;(feature?)

                                ;               end;

 0085  FF 44 0C                         INC     WP [SI]+12      ;next ITER
 0088  8B 54 0C                         MOV     DX,WP [SI]+12   ;DX is bombed so use memory variable
 008B  81 FA 03E8                       CMP     DX,1000         ;DX is loaded for possible use at top
 008F  7E 90                            JLE     L2              ; of loop

                                ;       end;

 0091  33 C0                            XOR     AX,AX           ;device 0
 0093  50                               PUSH    AX
 0094  8B 44 0A                         MOV     AX,WP [SI]+10   ;COUNT
 0097  0E                               PUSH    CS
 0098  E8 0000 E                        CALL    NEAR PTR INTR11 ;INTOUT intrinsic
 009B  33 C0                            XOR     AX,AX           ;device 0
 009D  50                               PUSH    AX

 0011                           DSEG    SEGMENT WORD PUBLIC 'DATA'

 0011 20 70 72 69 6D 65         L10     DB      " primes",13,""
       73 0D 8A
 009E                           DSEG    ENDS

 009E  B8 0011 R                        MOV     AX,OFFSET L10   ;address of string
 00A1  0E                               PUSH    CS
 00A2  E8 0000 E                        CALL    NEAR PTR INTR12 ;TEXT intrinsic
                                ; INTOUT(0, COUNT);   TEXT(0, " primes
                                ; ");                                           \primes found in 1000th pass

 00A5  CB                               RETF                    ;return to NATIVEX, which normally
                                ; end;                          ; returns to DOS

                                        PUBLIC  PROGRM
 00A6                           CSEG    ENDS
                                        END
;= 166 bytes (not including text strings in the data segment)
