News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Linking programs

Started by veronicak5678, October 09, 2009, 02:33:44 AM

Previous topic - Next topic

MichaelW

Try right-clicking on the EXE and selecting Properties on the context menu, then on the Program tab clear the Close on exit checkbox.

eschew obfuscation

veronicak5678

There is no Program tab. There is General, Compatibility, Summary.

MichaelW

If there is no Program tab then the file is a 32-bit Windows program. I am referring to the main.exe from Dave's Random3.zip attachment, which is a 16-bit DOS program.
eschew obfuscation

veronicak5678

It is almost done. The only problem left is my strings are coming out as garbage. The numbers show up fine, but my headers are mumbo-jumbo. Can anyone see why?

;===================================================================
;                   MAIN.ASM
;===================================================================
         EXTERN  GETDEC:FAR
         EXTERN  NEWLINE:FAR
         EXTERN  PUTSTRNG:FAR
         EXTERN  NRANDOM:FAR
         EXTERN  RESEED:FAR
         EXTERN  PUTDEC:FAR
;===================================================================
        .MODEL  LARGE
        .STACK  512     
;===================================================================
; D A T A   S E G M E N T   D E F I N I T I O N
        .DATA
UPPER      DW 9999
LOWER      DW 0
HIGHCOUNT  DW 0
LOWCOUNT   DW 0
EVENCOUNT  DW 0
ODDCOUNT   DW 0
LOOPER     DW 0
HIGHHEADER DB 'High: '
LOWHEADER  DB 'Low:  '
ODDHEADER  DB 'Odd:  '
EVENHEADER DB 'Even: '
SPACE      DB '  '
;===================================================================
; C O D E   S E G M E N T   D E F I N I T I O N
        .CODE
        ASSUME  DS:DGROUP
;-------------------------------------------------------------------
MAIN    PROC
        MOV     AX,DGROUP           ;SET DS-REGISTER TO POINT TO
        MOV     DS,AX               ;DATA SEGMENT
        MOV     BL,1   
        CALL    RESEED
        MOV     LOOPER,100          ;LOOP_COUNT = 100
NUM_LOOP:
        MOV     CX,10               ;LOOP_COUNT = 10
LINE_LOOP:
        PUSH    CX                  ;      PUSH LOOP_COUNT
        MOV     AX,UPPER            ;PUSH UPPER
        PUSH    AX
        MOV     AX,LOWER            ;PUSH LOWER
        PUSH    AX 
        CALL    NRANDOM
        MOV     BH,1
        CALL    PUTDEC
LEA     DI, SPACE
        MOV     CX, 1
        CALL    PUTSTRNG
        CMP     AX,5000
        JAE     HIGH_SEQUENCE   
        INC     LOWCOUNT
        JMP SHORT HILO_COUNTED
HIGH_SEQUENCE:
        INC     HIGHCOUNT
HILO_COUNTED:
        SHR     AX,1
        JC      ODDS
        INC     EVENCOUNT
        JMP     SHORT EVENODD_COUNTED
ODDS:
        INC     ODDCOUNT
EVENODD_COUNTED:
        POP     CX                   ;     POP LOOP_COUNT
        LOOP    LINE_LOOP            ;     DECREMENT LOOP_COUNT
CALL    NEWLINE
        SUB     LOOPER,10            ;     POP LOOP_COUNT
        CMP     LOOPER,0
JNE     NUM_LOOP

;============display
                CALL    NEWLINE
                CALL    NEWLINE

LEA     DI, HIGHHEADER
                MOV     CX, 6
                CALL    PUTSTRNG
        MOV     AX, HIGHCOUNT
                CALL    PUTDEC
                CALL    NEWLINE

LEA     DI, LOWHEADER
                MOV     CX, 6
                CALL    PUTSTRNG
        MOV     AX, LOWCOUNT
                CALL    PUTDEC
                CALL    NEWLINE

LEA     DI, EVENHEADER
                MOV     CX, 6
                CALL    PUTSTRNG
        MOV     AX, EVENCOUNT
                CALL    PUTDEC
                CALL    NEWLINE

LEA     DI, ODDHEADER
                MOV     CX, 6
                CALL    PUTSTRNG
        MOV     AX, ODDCOUNT
                CALL    PUTDEC
                CALL    NEWLINE


;==================
        MOV     AX,4C00H
        INT     21H
MAIN ENDP                       
        END MAIN


;===================================================================
;                   RANDOM.ASM
;      r a n d o m   n u m b e r   g e n e r a t o r
; GENERATES PSEUDO-RANDOM INTEGERS IN THE RANGE LOWER TO UPPER
; INPUT:  TWO STACK PARAMETERS - LOWER AND UPPER ENDS OF RANGE
; OUTPUT: AX-REG CONTAINS RANDOM INTEGER
; CALLING SEQUENCE:     PUSH    <LOWER END OF RANGE>
;                       PUSH    <UPPER END OF RANGE>
;                       CALL    RANDOM
;===================================================================
         .MODEL  LARGE     
;===================================================================
        PUBLIC  SEED
        PUBLIC  RESEED
        PUBLIC  NRANDOM
;===================================================================
; D A T A   S E G M E N T   D E F I N I T I O N
        .FARDATA
SEED       DW      ?                   ;SEED FOR RANDOM NUMBER GEN.
MULTIPLIER DW      25173               ;MULTIPLIER AND
ADDEND     DW      13849               
;===================================================================
; C O D E   S E G M E N T   D E F I N I T I O N
        .CODE   
        ASSUME  DS:NOTHING,ES:FAR_DATA
;-------------------------------------------------------------------

RESEED  PROC    FAR PUBLIC USES AX CX DX ES
        MOV     AX,FAR_DATA            ;SET ES-REGISTER TO POINT
        MOV     ES,AX                  ;TO FAR DATA SEGMENT
        PUSHF                         
        cmp bl,0
        jne     NOTZERO
        mov     dx,5555h
        MOV     AH,0                   ;     SEED = LOWER HALF OF
        INT     1AH                    ;            TIME OF DAY CLOCK
        jmp endd
NOTZERO:
        MOV     SEED,5555h
endd:
        POPF                         
        RET                           
RESEED  ENDP                     


NRANDOM PROC    FAR PUBLIC
        PUSH    CX                     ;( [BP+8] )
        PUSH    DX                     ;( [BP+6] )
        PUSH    ES                     ;( [BP+4] )
        PUSHF                          ;SAVE FLAGS ( [BP+2] )
        PUSH    BP                     ;( [BP+0] )
        MOV     BP,SP
        MOV     AX,FAR_DATA            ;SET ES-REGISTER TO POINT
        MOV     ES,AX                  ;TO FAR DATA SEGMENT
        MOV     AX,SEED                ;X = SEED * MULTIPLIER mod 65536
        MUL     MULTIPLIER
        ADD     AX,ADDEND              ;SEED = (X + ADDEND) mod 65536
        MOV     SEED,AX
        MOV     CX,[BP+16]             ;UPPER - RANGE = UPPER - LOWER + 1
        SUB     CX,[BP+14]             ;LOWER
        INC     CX
        MUL     CX                     ;RANDOM = (SEED*RANGE)/65536
        ADD     DX,[BP+14]             ;                    + LOWER
        MOV     AX,DX
        POP     BP
        POPF                           ;RESTORE FLAGS
        POP     ES                     ;RESTORE REGISTERS
        POP     DX
        POP     CX
        RET     4                      ;RETURN (RANDOM)
NRANDOM ENDP                           ;END NRANDOM
        END 

dedndave

i had trouble making PutStrng work for me
in the documentation, it says it is a near procedure
when i try to link it as near, the linker has to do "fix-ups" (usually an indication of a problem like near/far)
when i link it as far, the linker does not do fix-ups, but i got garbage out
i disassembled some of the library code and found procedures in there using far returns
yet, all of the procedures in the documentation are specified as near procedures
at that point, i used int 21h, function 9 to display strings instead of PutStrng and it worked fine

dedndave

#80
i think the documentation you sent me is for a different library named UTIL.LIB
at any rate, i disassembled these library functions to see how regstiers are used
they are indeed FAR procedures - not NEAR like the document says
they are also all capital letters - again, not matching the document

;---------------------------------------------------------------------------------------------

PUTSTRNG requires the string be pointed to by ES:[DI] and be CX bytes long
so, for that part of the program, get DGROUP into the ES register and it should work
make sure that RESEED and NRANDOM preserve the ES register (i think i did that - lol)

        MOV     AX,DGROUP           ;SET DS-REGISTER TO POINT TO
        MOV     DS,AX               ;DATA SEGMENT
        MOV     ES,AX               ;AND ES

GETDEC appears to return a 16-bit signed binary value in AX from keyboard entry - very strangely written routine - lol

NEWLINE has no input parameters and has no output other than a carriage return/line feed to the display

PUTDEC displays a 16-bit signed integer from AX to the display
if BH is 0, the string is left-justified, if BH is non-zero, the string is right-justified in a 6-character field

;---------------------------------------------------------------------------------------------

i see you muddled with RESEED - lol

        cmp bl,0
        jne     NOTZERO
        mov     dx,5555h          ;<-------------------------------------- take this line out
        MOV     AH,0                   ;     SEED = LOWER HALF OF
        INT     1AH                    ;            TIME OF DAY CLOCK
        MOV     SEED,DX         ;<-------------------------- oops - you forgot that line
        jmp short endd            ;<-------------------------------------- add the short
NOTZERO:
        MOV     SEED,5555h
endd:

;---------------------------------------------------------------------------------------------

your loop structure is a little strange
you can use the CX register and LOOP for both inner and outer loops (and get rid of LOOPER)

        MOV     CX,10               ;LINE COUNT = 10

NUM_LOOP:
        PUSH    CX                  ;SAVE OUTER LOOP COUNT
        MOV     CX,10               ;NUMBERS PER LINE COUNT = 10

LINE_LOOP:
        PUSH    CX                  ;SAVE INNER LOOP OCUNT
.
.
.
        POP     CX                  ;RECALL INNER LOOP COUNT
        LOOP    LINE_LOOP

        CALL    NEWLINE
        POP     CX                  ;RECALL OUTER LOOP COUNT
        LOOP    NUM_LOOP

i would swap the names NUM_LOOP and LINE_LOOP - they make more sense reversed
swap them at both the top and the bottom

;---------------------------------------------------------------------------------------------

you are using LEA to get the offsets into DI - use MOV DI,offset___ instead

        LEA     DI, HIGHHEADER

mov is shorter and faster

        MOV     DI,OFFSET HIGHHEADER

depending on how the segments are ordered, you sometimes may have to use DGROUP:
(i don't think you need it in this case, but i thought i would mention it)

        MOV     DI,OFFSET DGROUP:HIGHHEADER

;---------------------------------------------------------------------------------------------

instead of counting characters and putting numbers into CX, use the SIZEOF operator
not only do you not have to count characters (a good place for mistakes),
but if you change the string, the count automatically changes for you

        MOV     CX,SIZEOF HIGHHEADER

;---------------------------------------------------------------------------------------------

one last note:
i could have used the DS register for the far routines instead of ES
you can get FAR_DATA into the DS register, so long as that register is preserved
by using ES, all of the references to the FAR_DATA area use a segment override (the assembler adds them)

        .CODE   
        ASSUME  DS:FAR_DATA   ;<------------- change
.
.
.
RESEED  PROC    FAR PUBLIC USES AX CX DX DS         ;<-------notice the change here
        MOV     AX,FAR_DATA            ;SET DS-REGISTER TO POINT <------------- change the comment
        MOV     DS,AX                  ;TO FAR DATA SEGMENT <------------- change
.
.
.
NRANDOM PROC    FAR PUBLIC
        PUSH    CX                     ;( [BP+8] )
        PUSH    DX                     ;( [BP+6] )
        PUSH    DS                     ;( [BP+4] )             <------------- change
        PUSHF                          ;SAVE FLAGS ( [BP+2] )
        PUSH    BP                     ;( [BP+0] )
        MOV     BP,SP
        MOV     AX,FAR_DATA            ;SET DS-REGISTER TO POINT <------------- change the comment
        MOV     DS,AX                  ;TO FAR DATA SEGMENT <------------- change
.
.
.
        POP     BP
        POPF                           ;RESTORE FLAGS
        POP     DS                     ;RESTORE REGISTERS   <------------- change
        POP     DX
        POP     CX
        RET     4                      ;RETURN (RANDOM)
NRANDOM ENDP                           ;END NRANDOM

dedndave

i made those changes and added a few things - lol
see attached file

Enter 0 for Random Seed or 1 for 5555h Seed and Range 0-9999: 1

   832   6809   8658   1206   5968   8066   3916   5338   8185   6129
  2739   7450   3575   8968   2470   1758    732   7051   2952   4983
   751   3347   6531   6342   7225   3324   8049   7555   6248   4952
  4850   2840   6413   8699   6778   8916   8815   7534   6177   5001
  7047   6925   7890   2816   7203   4842   9262   6577   7876   1753
   135   3005    160    627   2854   1317   7650   6932   2263   3233
  6438   8638   5704   2971   5119   6213   3023   7251   4787   2626
  6563   5290   9034   3346   1166   8807   3955   6341   4179   2022
  8144   2080   5443   1652   2695   3532   7302   6918   1200   6166
  4602   9537   9754   7950   4684   3728   6950   9353   7393   6211


High:     56
Low:      44
Even:     54
Odd:      46

Enter 0 to Exit or 1 to Run Again: 1

Enter 0 for Random Seed or 1 for 5555h Seed and Range 0-9999: 0

Enter Lower End of Range: 300

Enter Upper End of Range: 500

   348    498    384    399    357    383    348    324    366    385
   323    497    410    426    470    461    373    477    395    416
   389    360    360    408    443    347    474    333    368    361
   496    340    451    372    435    424    424    403    350    432
   473    325    352    462    430    461    399    460    382    382
   301    422    462    310    318    397    455    318    358    481
   395    327    382    420    366    308    397    411    303    485
   465    302    390    327    493    390    463    359    442    420
   403    350    320    391    347    324    389    348    480    352
   355    390    433    356    380    462    494    307    473    361


High:     41
Low:      59
Even:     54
Odd:      46

Enter 0 to Exit or 1 to Run Again: 0

hutch--

This is from a long time ago and I confess to being 15 years out of date with DOS software but something looked wrong in this directive,


           .MODEL  SMALL,BASIC


A very long time ago when I used to write assembler modules in MASM for Microsoft basic you always used,


           .MODEL  MEDIUM,BASIC


From memory you cannot access FAR data from a small memory model, MEDIUM, LARGE and HUGE are the ones that could handle FAR addressed segments.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

dedndave

we got her to LARGE, Hutch - lol
she wanted to use multiple code and data segments
i modified the last d/l so it works with negative range values

Enter 0 for Random Seed or 1 for 5555h Seed and Range 0-9999:

Enter Lower End of Range: -3000

Enter Upper End of Range: -2000

-2263  -2532  -2621  -2754  -2878  -2780  -2387  -2660  -2299  -2176
-2187  -2972  -2670  -2672  -2037  -2015  -2879  -2973  -2703  -2872
-2567  -2529  -2700  -2368  -2125  -2546  -2293  -2081  -2695  -2977
-2498  -2341  -2165  -2522  -2082  -2225  -2178  -2638  -2559  -2561
-2124  -2526  -2195  -2927  -2142  -2139  -2006  -2651  -2125  -2182
-2758  -2812  -2712  -2106  -2966  -2237  -2294  -2115  -2895  -2506
-2011  -2162  -2561  -2946  -2756  -2951  -2731  -2634  -2167  -2934
-2919  -2399  -2636  -2313  -2391  -2820  -2303  -2044  -2163  -2224
-2059  -2829  -2000  -2690  -2545  -2120  -2419  -2044  -2150  -2121
-2685  -2868  -2016  -2786  -2812  -2487  -2034  -2817  -2567  -2980


High: 48
Low:  52
Even: 50
Odd:  50

Enter 0 to Exit or 1 to Run Again:

japheth

Quote from: hutch-- on October 10, 2009, 12:46:19 PM
From memory you cannot access FAR data from a small memory model, MEDIUM, LARGE and HUGE are the ones that could handle FAR addressed segments.

Perhabs it's time to learn Masm, finally? After maintaining a Masm forum for so many years ...

veronicak5678

Wow! Thank you so much for all your help, Dave. This really would have been a mess if I had done it alone.

dedndave

no problem, Veronica
i was working on something else and needed a break from it to let it tumble around in my head - lol
this wasn't too hard, so i had 5 brain cells left to work on that at the same time   :P

ilian007

what if we decide to separate the Ressed PROC in separate file? can we easily do that ? and have 3 files main.asm, reseed.asm random.asm

dedndave

certainly
you will just have to link 3 OBJ's (with the LIB, of course) together instead of 2
furthermore, the NRANDOM and RESEED OBJ's could be put into another library, or added to the IO.LIB library
that is how large projects are sometimes managed
or - if you have a set of commonly used routines

ilian007

#89
Somehow when I separate it in a file the printing numbers are not what they have to be for 5555h and always printing same ones when using the clock ... thats what I have. I believe there is problem with the definition of UPPER and LOWER if that is the issue I dont really know how to fix it ... First massive is printing 100 numbers using clock. second is printing using 5555h for SEED


;===================================================================
;              MAIN.ASM of Random Numnbers
;
;
;===================================================================
             .MODEL  LARGE
.STACK 256
;===================================================================
                                       ;PROCEDURES TO
           
   EXTRN   NRANDOM:FAR          ;PROCEDURE RANDOM   
           EXTRN   RESEED:FAR          ;PROCEDURE RESEED
           EXTRN   CLEAR:FAR           ;CLEAR SCREEN
           EXTRN   NEWLINE:FAR         ;DISPLAY NEWLINE CHARACTER
           EXTRN   PAUSE:FAR           ;PAUSE UNTIL KEY STROKE
           EXTRN   PUTDEC:FAR
           EXTRN   PUTSTRNG:FAR        ;DISPLAY CHARACTER STRING
;===================================================================
;DATA  S E G M E N T   D E F I N I T I O N
;
  .DATA

UPPER     DW 9999 ; set value for UPPER
LOWER     DW 0    ; set value for LOWER
COUNTEVEN   DW 0
COUNTODD    DW 0
COUNTHIGH   DW 0
COUNTLOW    DW 0
COUNTER     DW 0

HEADERHIGH  DB 'High 5000-9999: '
HEADERLOW   DB 'Low 0-4999:     '
HEADEREVEN  DB 'Even:           '
HEADERODD   DB 'ODD:            ' 
SPACE     DB ' '
PAUSE_MSG  DB      '   ANY KEY CONTINUES '
;OURSEED     DB 'Numbers Using SEED 5555h are: '
;CLOCKSEED   DB 'Numbers USING CLOCK SEED are: '

;===================================================================
;C O D E   S E G M E N T   D E F I N I T I O N
;
           .CODE
           ASSUME  DS:DGROUP
;-------------------------------------------------------------------
MAIN PROC

        MOV  AX,DGROUP    ;SET DS-REGISTER TO POINT TO
        MOV  DS,AX               ;CONSTANT DATA SEGMENT
MOV  BL,0
start:
CALL RESEED
MOV  COUNTER,100 ;SET LOOP COUNTS 0 to 100
NUM_LOOP:
MOV  CX,10 ;SET TO LOOP 10 numbers per line
LINE_LOOP:
PUSH  CX
        MOV  AX,UPPER    ;MOVE UPPER IN AX REGISTER 9999
        PUSH AX         ; PUSH AX VALUE INTO THE STACK
MOV  AX,LOWER    ;MOVE LOWER IN AX REGISTER 0
PUSH AX ;PUSH AX VALUE INTO THE STACK

CALL NRANDOM ;CALL PROC RANDOM
MOV  BH,+1
CALL PUTDEC
LEA  DI,SPACE
MOV  CX,1
CALL PUTSTRNG
CMP  AX,5000
JAE  SEQHIGH
INC  COUNTLOW
JMP  SHORT HILO_COUNTER
SEQHIGH:
INC  COUNTHIGH

HILO_COUNTER:
SHR  AX,1
JC   ODDS
INC  COUNTEVEN
JMP  SHORT EVENODD_COUNTER
ODDS:
INC  COUNTODD
EVENODD_COUNTER:
POP  CX
LOOP LINE_LOOP
CALL NEWLINE
SUB  COUNTER,10
CMP  COUNTER,0
MOV AX,DGROUP
MOV  ES,AX
JNE  NUM_LOOP

; ======= PRINT STATISTIC OF NUMBERS ON SCREEN========



CALL NEWLINE
INC  BL
CMP  BL,1
JE   START
CALL NEWLINE
CALL NEWLINE

LEA  DI,HEADERHIGH
MOV  CX,16
CALL PUTSTRNG
MOV  AX, COUNTHIGH
CALL PUTDEC
CALL NEWLINE

LEA  DI,HEADERLOW
MOV  CX,16
CALL PUTSTRNG
MOV  AX,COUNTLOW
CALL PUTDEC
CALL NEWLINE

LEA  DI,HEADEREVEN
MOV  CX,16
CALL PUTSTRNG
MOV  AX,COUNTEVEN
CALL PUTDEC
CALL NEWLINE

LEA DI,HEADERODD
MOV CX,16
CALL PUTSTRNG
MOV AX, COUNTODD
CALL PUTDEC
CALL NEWLINE

CALL    NEWLINE             ;   DISPLAY NEWLINE CHAR.
LEA     DI,PAUSE_MSG        ;   PAUSE AND WAIT FOR
        MOV     CX,21               ;   KEY STROKE
        CALL    PAUSE

       

;========= END PRINT STATISTIC OF NUMBERS ON SCREEN ;
.exit
MAIN ENDP                       
        END MAIN

;===================================================================
;                   RESEED.ASM
;      r a n d o m   n u m b e r   g e n e r a t o r
;
; GENERATES PSEUDO-RANDOM INTEGERS IN THE RANGE LOWER TO UPPER
; INPUT:  TWO STACK PARAMETERS - LOWER AND UPPER ENDS OF RANGE
; OUTPUT: AX-REG CONTAINS RANDOM INTEGER
; CALLING SEQUENCE:     PUSH    <LOWER END OF RANGE>
;                       PUSH    <UPPER END OF RANGE>
;                       CALL    RANDOM
;===================================================================
           .MODEL  SMALL,BASIC
;===================================================================
EXTRN   NRANDOM:FAR

PUBLIC SEED
PUBLIC RESEED

;===================================================================
; D A T A   S E G M E N T   D E F I N I T I O N
           .FARDATA
SEED       DW      ?                   ;SEED FOR RANDOM NUMBER GEN.
;MULTIPLIER DW      25173               ;MULTIPLIER AND
;ADDEND     DW      13849               ;ADDEND FOR MIXED

;===================================================================
; C O D E   S E G M E N T   D E F I N I T I O N
;
           .CODE   
           ASSUME  DS:FAR_DATA
;---------------------------------------------------------------------
RESEED  PROC    FAR PUBLIC USES AX CX DX DS
        MOV     AX,FAR_DATA            ;SET DS-REGISTER TO POINT
        MOV     DS,AX                  ;TO FAR DATA SEGMENT
        PUSHF                         
        cmp bl,0
        jne     NOTZERO
        MOV     AH,0                   ;     SEED = LOWER HALF OF
        INT     1AH                    ;            TIME OF DAY CLOCK
MOV SEED,DX
        jmp short endd
NOTZERO:
        MOV     SEED,5555h
endd:
        POPF                         
        RET                           
RESEED  ENDP                     
END           

   
;===================================================================
;                   RAND.ASM
;      r a n d o m   n u m b e r   g e n e r a t o r
;
; GENERATES PSEUDO-RANDOM INTEGERS IN THE RANGE LOWER TO UPPER
; INPUT:  TWO STACK PARAMETERS - LOWER AND UPPER ENDS OF RANGE
; OUTPUT: AX-REG CONTAINS RANDOM INTEGER
; CALLING SEQUENCE:     PUSH    <LOWER END OF RANGE>
;                       PUSH    <UPPER END OF RANGE>
;                       CALL    RANDOM
;===================================================================
           .MODEL LARGE
;===================================================================

PUBLIC NRANDOM
;===================================================================
; D A T A   S E G M E N T   D E F I N I T I O N
           .FARDATA
SEED       DW      ?                   ;SEED FOR RANDOM NUMBER GEN.
MULTIPLIER DW      25173               ;MULTIPLIER AND
ADDEND     DW      13849               ;ADDEND FOR MIXED
UPPER    DW      9999
LOWER    DW      0
;===================================================================
; C O D E   S E G M E N T   D E F I N I T I O N
;
           .CODE   
           ASSUME  DS:FAR_DATA
;---------------------------------------------------------------------
             


NRANDOM PROC    FAR PUBLIC
   
       
        PUSH    DS                     ;
        PUSHF                          ;SAVE FLAGS
       
        MOV     AX,FAR_DATA            ;SET DS-REGISTER TO POINT
        MOV     DS,AX                  ;TO FAR DATA SEGMENT
        MOV     AX,SEED                ;X = SEED * MULTIPLIER mod
        MUL     MULTIPLIER          ;                       65536
        ADD     AX,ADDEND           ;SEED = (X + ADDEND) mod 65536
        MOV     SEED,AX
        MOV     CX,UPPER            ;RANGE = UPPER - LOWER + 1
        SUB     CX,LOWER
        INC     CX
        MUL     CX                  ;RANDOM = (SEED*RANGE)/65536
        ADD     DX,LOWER                ;                    + LOWER
        MOV     AX,DX
        POPF                           ;RESTORE FLAGS
        POP     DS                     ;RESTORE REGISTERS
       
        RET     4                      ;RETURN (RANDOM)
NRANDOM ENDP                           ;END NRANDOM
        END 


IF the RSEED PROC portion is in the random.asm everything works perfect when separate it in own file it doesnt. still prints but not what it is supposed to ...
Thank you

Edit: Added code tags