News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

search and print

Started by Pokerice, May 28, 2014, 03:03:38 PM

Previous topic - Next topic

Pokerice

Hi, I am trying to make a simple 16 bit .COM program which basically tries to see if a file exists or not. But it either freezes my command prompt or tells me it encountered some illegal instructions (double clicking the .com file).
Here is my code:

.model tiny

.code

ORG 100H

Start:
        mov ah, 4EH                          ;prepares search first function
        mov dx, offset STRING_LC     ;offset
        mov cx, 0                               ;read only
        int 21
        JC NoFile

File:
        mov ah, 9
        mov dx, offset msg
        int 21
        jc Done
       
NoFile:
        mov ah, 9
        mov dx, offset msg2
        int 21

Done:   
        mov ah, 9
        mov dx, offset msg3
        int 21
     

STRING_LC DB    '*.txt',0        ;file/files looking for

msg3 db 'finish$'
msg db  'file found$'
msg2 db 'file not found$'

END Start

sinsi

int 21
try int 21h

Also
jc Done
try jmp Done

Pokerice

thank you!!! Silly mistake using jc instead of jmp and I guess you can't leave out the hex :biggrin:

Gunther

Hi Pokerice,

Apart from the errors, I can't see the part for going back to DOS. Something like:

         mov        ax, 4c00h
         int        21h


Gunther
You have to know the facts before you can distort them.

sinsi

Quote from: Gunther on May 28, 2014, 05:12:44 PM
Hi Pokerice,

Apart from the errors, I can't see the part for going back to DOS. Something like:

         mov        ax, 4c00h
         int        21h


Gunther
Ha! Well spotted. My excuse? Beer goggles...

Gunther

Hi sinsi,

beer would be nice. :lol:

Gunther
You have to know the facts before you can distort them.

Pokerice

haha thanks gunther 8) 

By the way, using ret is the same right?

sinsi

As long as the stack is balanced then RET will work, but only for a .com file.
From memory, the top of the stack is 0, so it RETs to CS:0000, which is an INT 20H.

Better to use the approved way as Gunther has.

dedndave

i think the JC might be ok
but, there is a FindFirst function, and a FindNext function
i haven't used it for years - lol

RET is ok for a .COM, exactly as Sinsi mentioned
for .EXE's, they used to...
main    PROC    FAR

    xor     ax,ax   ;zero AX
    push    ds      ;initially, the DS register holds the PSP segment
    push    ax

;main code

    ret

main    ENDP

        END     main

because "main" is typed as FAR, the RET at the end will be a RETF
so, it branches to PSP:0

main should be typed as NEAR for a .COM program

INT 21h, AH=4Ch is prefered

Pokerice

Thanks.. but dedndave, you have completely lost me at the "...typed as FAR, the RET...." part. :lol:

Gunther

Pokerice,

Quote from: Pokerice on May 28, 2014, 11:45:43 PM
Thanks.. but dedndave, you have completely lost me at the "...typed as FAR, the RET...." part. :lol:

Don't be afraid. In your COM file (limited to 64 KB) are all procedures by defintion near (same segment). Change the FAR to NEAR and the assembler generates the appropriate RET machine code.

But you'll do safe if you use INT 21h with AX = 4c00h. That works for COM and EXE files and - not to forget - for 16-bit Windows applications, too.

Gunther
You have to know the facts before you can distort them.

dedndave

here is what i use as a Small model EXE template

        .MODEL  Small
        .STACK  4096
        .DOSSEG
        .386
        OPTION  CaseMap:None

;####################################################################################

        .DATA

s$Msg   db 'Hello World !',0Dh,0Ah,24h

;************************************************************************************

        .DATA?

;####################################################################################

        .CODE

;************************************************************************************

_main   PROC    FAR

        mov     dx,@data
        mov     ds,dx

        mov     dx,offset s$Msg
        mov     ah,9
        int     21h

        mov     ax,4C00h
        int     21h

_main   ENDP

;####################################################################################

        END     _main


here is what i use as a Tiny model COM template

        .MODEL  Tiny
        .386
        OPTION  CaseMap:None

;####################################################################################

        .CODE

;************************************************************************************

        ORG     100h

_main   PROC    NEAR

        mov     dx,offset s$Msg
        mov     ah,9
        int     21h

        mov     ax,4C00h
        int     21h

_main   ENDP

;####################################################################################

s$Msg   db 'Hello World !',0Dh,0Ah,24h

;####################################################################################

        END     _main


notice that the COM PROC is typed as NEAR
although - it's not needed, as NEAR is the default type

FORTRANS

Quote from: Pokerice on May 28, 2014, 11:45:43 PM
Thanks.. but dedndave, you have completely lost me at the "...typed as FAR, the RET...." part. :lol:

Hi,

   When you jump to, (or call) a routine in the same segment, it is
a NEAR jump, you use only an offset from the current position.
When the code is in a different segment, you need a FAR jump (or
call) specifying both a segment and an offset into that segment.

   In a *.COM program, the PSP, code, data, and stack are all in the
same segment on program load.  A *.EXE program has separate
segments for the PSP and code when the program loads.  It should
(mostly) also have separate segments for the stack and data.

Regards,

Steve N.

dedndave

try this one

        .MODEL  Tiny
        .386
        OPTION  CaseMap:None

;####################################################################################

        .CODE

;************************************************************************************

        ORG     100h

_main   PROC    NEAR

        xor     cx,cx                 ;file attribute = 0
        mov     dx,offset szTxtExt
        mov     ax,4E00h              ;Find First File
        int     21h
        mov     dx,offset s$NotFound
        jc      ShowMessage

        mov     dx,offset s$Found

ShowMessage:
        mov     ah,9
        int     21h

        mov     dx,offset s$Finish
        mov     ah,9
        int     21h

        mov     ax,4C00h
        int     21h

_main   ENDP

;####################################################################################

szTxtExt   db '*.txt',0

s$Found    db 'File Found',13,10,24h
s$NotFound db 'File Not Found',13,10,24h
s$Finish   db 'Finish',13,10,24h

;####################################################################################

        END     _main

Pokerice

Thank you all of you 8)! Esepcially FORTRANS for the clear explanation :biggrin:

With that being said, can you use PROC NEAR for some code and PROC FAR for others?
Also, regarding to the segments, do some memory block just get automatically allocated as a certain segment or is it always a specific memory block? Say for DOS, since only one segment,
does it just generate 64kb of memory randomly for your program to use?