• Please review our updated Terms and Rules here

Mem command for older DOS versions

snq

Experienced Member
Joined
Mar 29, 2009
Messages
164
Location
Sweden, way up north
I'm not sure when MEM was introduced but my DOS 3.3 doesn't have it and I've actually missed it a bit.. So I baked my own version and figured I may as well share it here :)
It turned out to be 41 bytes, if anyone can see a way to make it smaller please post!

Download below, and here is the source too.
Code:
;nasm -fbin -omem.com mem.asm

cpu 8086
bits 16
org 100h

    ; Try to resize our current block to 0FFxxh paragraphs
    ; This will fail and report max paragraphs available in BX
    mov     bh, 0FFh
    mov     ah, 4Ah
    int     21h

    ; Divide by (1024/16)
    ; On 286+ we can shr ax,6 directly and save 1 byte
    xchg    ax, bx
    mov     cl, 6
    shr     ax, cl

    ; Convert to string, starting with the last digit
    ; Overwrites code we don't need any more, to save space
    jmp     short skipString
digitsGoHere:
    db 'k$'
skipString:

    mov     bl, 10
    mov     di, digitsGoHere
convertLoop:
    dec     di
    div     bl
    add     ah, '0'
    mov     [di], ah
    xor     ah, ah
    test    al, al
    jnz     short convertLoop

    ; Output string, we have our pointer in DI
    mov     ah, 9
    mov     dx, di
    int     21h

    ret
 

Attachments

  • mem.zip
    153 bytes · Views: 11

Chuck(G)

25k Member
Joined
Jan 11, 2007
Messages
40,853
Location
Pacific Northwest, USA
How about this one, from 20 or so years ago? Does disk drives, conventional, EMS and XMS; computes percentages.
 

Attachments

  • SSTAT.ZIP
    10.9 KB · Views: 11

snq

Experienced Member
Joined
Mar 29, 2009
Messages
164
Location
Sweden, way up north
That works but really does more than I want... And this is the programming forum after all so where's the fun in using something existing ;) I've typed mem at least a dozen times and keep forgetting its not there, hence the replacement.
And if I may nitpick a bit, sstat also shows there's more memory available than there actually is because they round up instead of down.
 

Ole Juul

Veteran Member
Joined
Aug 15, 2008
Messages
3,982
Location
Coalmont, BC, Canada
snq: I'm not sure when MEM was introduced but my DOS 3.3 doesn't have it and I've actually missed it a bit.. So I baked my own version and figured I may as well share it here

That's nice and small and could be useful so I'll keep it. Thanks!

MEM was introduced in v4.0, however CHKDSK which works just fine was introduced in v1.0

I know this is the Programming forum but there is no reason to miss anything in DOS, for example this directory is full of memory utilities. :) I would hope that most DOS users have downloaded what they want from there by now since it's no longer as troublesome as it was with 2400baud.

Chuck(G): How about this one, from 20 or so years ago? Does disk drives, conventional, EMS and XMS; computes percentages.

That's a nice layout but the first 5 lines scroll off the screen because of the note at the bottom so it needs to be piped or something. Also it shows one of my substitute drives (X: ) but it missed the other one (B: ). I guess it's a nuisance to accommodate lunies like me who do something like use B: with SUBST. Hey, the alphabet is short enough as it is and I'm not going to waste a perfectly good letter! Also, I'm not complaining but perhaps you'd like to know that it shows garbage for my extended memory, perhaps because I'm using JEMMEX as my memory manager.

Code:
Extended     �             0 �4,294,903,185    0.0% �       64,111    0.0%

BTW: is that Sydex BBS still runnig? :p
 

nige the hippy

Veteran Member
Joined
Apr 7, 2006
Messages
1,282
Location
Luton UK
Slightly o/t but a few weeks ago I wondered how much memory I had on my machine (running win 2k). Being one click away from a command prompt, I typed "mem" and got this back...



655360 bytes total conventional memory
655360 bytes available to MS-DOS
627056 largest executable program size

1048576 bytes total contiguous extended memory
0 bytes available contiguous extended memory
941056 bytes available XMS memory
MS-DOS resident in High Memory Area


Looks like it hasn't been updated for a while!
 

Chuck(G)

25k Member
Joined
Jan 11, 2007
Messages
40,853
Location
Pacific Northwest, USA
The rounding is intentional--probably done on someone's requrest. I'd forgotten that I even wrote the thing until snq posted his thing.

Feel free to tinker with the code--it was an advertising freebie (it may be included in some of the old McGraw-Hill utilities disks). It comes from a time when 4GB was an enormous drive, bigger than anything on the market.

The notable thing is not the stuff that fetches the memory, but the COBOL-style numeric editing routine (note the "picture" strings early on in the program. This is a cut-down version from one that I wrote for a compiler that would do check-protect and implied ("V") decimals as well.

I think the BBS was taken off the air in 1996, but I can't recall exactly. I still have the hard drive from it and it still boots Windows NT 4.0.
 

snq

Experienced Member
Joined
Mar 29, 2009
Messages
164
Location
Sweden, way up north
I did put it in my utils dirs for when I want more info :) It's pretty cool that except for the rounding, your program and mine give the same results for memory available, even though the methods of obtaining the number are completely different.

Being an old demoscener I still always feel the need to optimize stuff, either for size or performance. Usually size because performance we got plenty of nowadays. Didn't really get started with the whole demoscene thing until the 16 bit era was pretty much over though, we did one 16 bit 64k intro written in pascal/asm and then moved on to pmode and later on win32.
 

snq

Experienced Member
Joined
Mar 29, 2009
Messages
164
Location
Sweden, way up north
So like I said, I like size optimizing.. Here's a version that is 40 bytes, and still works on 8086.
The change is the way I get the initial pointer to the end of the string. Call/pop instead of jmp/mov. Don't know how I missed that in the first place ;)

Code:
;nasm -fbin -omem.com mem.asm

cpu 8086
bits 16
org 100h

    ; Try to resize our current block to 0FFxxh paragraphs
    ; This will fail and report available paragraphs in BX
    mov     bh, 0FFh
    mov     ah, 4Ah
    int     21h

    ; Divide by (1024/16)
    ; On 286+ we can shr ax,6 directly and save 1 byte
    xchg    ax, bx
    mov     cl, 6
    shr     ax, cl

    ; Convert to string, starting with the last digit
    ; Overwrites code we don't need any more, to save space
    call    skipString
digitsGoHere:
    db 'k$'
skipString:
    pop     di              ; DI=digitsGoHere

    mov     bl, 10
convertLoop:
    dec     di
    div     bl
    add     ah, '0'
    mov     [di], ah
    xor     ah, ah
    test    al, al
    jnz     short convertLoop

    ; Output string, we have our pointer in DI
    mov     ah, 9
    mov     dx, di
    int     21h

    ret
 

Ole Juul

Veteran Member
Joined
Aug 15, 2008
Messages
3,982
Location
Coalmont, BC, Canada
@snq: Did you try CHDSK? For me it reports:

Code:
      655,360 total bytes memory
      629,648 bytes free

@Chuck(G): Actually it's a 6GB drive and (apart from a SUBST B: ) it managed all that perfectly:
Code:
 All Drives   �     6,062,340 �      318,032    5.2% �    5,744,308   94.8%
It was the 128MB RAM which went screwy.
 
Last edited:

Chuck(G)

25k Member
Joined
Jan 11, 2007
Messages
40,853
Location
Pacific Northwest, USA
What's the point of making something smaller than 1 sector? Takes the same amount of disk space; loads just as fast.

But you could save a byte by using the highest memory address in the PSP:

Code:
        mov  ax,ds:[2]
        mov  bx,ds
        sub  ax,bx
Will give you the largest contiguous area in memory in ax (which is all you really care about anyway).
 

Chuck(G)

25k Member
Joined
Jan 11, 2007
Messages
40,853
Location
Pacific Northwest, USA
Isn't the size of "smaller than one sector" programs still important when you put a bunch of them into one library such as with COMPAK.COM?

Only marginally, as most people don't use libraries--and then, there's the overhead of locating and extracting the program. On the other hand, it might be nice to tuck the code for this program into COMMAND.COM as an internal program.
 

snq

Experienced Member
Joined
Mar 29, 2009
Messages
164
Location
Sweden, way up north
But you could save a byte by using the highest memory address in the PSP:

Code:
        mov  ax,ds:[2]
        mov  bx,ds
        sub  ax,bx
Will give you the largest contiguous area in memory in ax (which is all you really care about anyway).
It does give the same result, but it's 1 byte larger for me, may just be nasm though.
mov ax, [ds:2] is 4 bytes, the other 2 instructions are 2 bytes each, so 8 in total. The first 4 lines of my code are 7 bytes together.

Oh and putting this in command.com or anything like that would make it one time use only, because part of the code is overwritten with the string that is outputted :)
 

vwestlife

Veteran Member
Joined
May 2, 2008
Messages
5,206
Location
central NJ
Slightly o/t but a few weeks ago I wondered how much memory I had on my machine (running win 2k). Being one click away from a command prompt, I typed "mem" and got this back...

655360 bytes total conventional memory
655360 bytes available to MS-DOS
627056 largest executable program size

1048576 bytes total contiguous extended memory
0 bytes available contiguous extended memory
941056 bytes available XMS memory
MS-DOS resident in High Memory Area

Looks like it hasn't been updated for a while!

Unfortunately, the DOS utilities included with every NT-family version of Windows (NT, 2000, XP, etc.) and every version of OS/2 since 2.0 are stuck at the equivalent of MS-DOS 5.0, so you miss out on the many updates and enhancements that were included in DOS 6.0 and higher. (And yet, the DOS within Windows XP still includes completely archaic and obsolete programs like EDLIN.)

In fact, it always annoyed me that Microsoft continued to make improvements to the MS-DOS 7.x subsystem of Windows 95 and 98, but yet almost none of these new features were carried over to the command line of the supposedly far superior Windows 2000 and XP.
 

MikeS

Veteran Member
Joined
Dec 23, 2005
Messages
7,510
Location
Toronto ON Canada
Unfortunately, the DOS utilities included with every NT-family version of Windows (NT, 2000, XP, etc.) and every version of OS/2 since 2.0 are stuck at the equivalent of MS-DOS 5.0, so you miss out on the many updates and enhancements that were included in DOS 6.0 and higher. (And yet, the DOS within Windows XP still includes completely archaic and obsolete programs like EDLIN.)

In fact, it always annoyed me that Microsoft continued to make improvements to the MS-DOS 7.x subsystem of Windows 95 and 98, but yet almost none of these new features were carried over to the command line of the supposedly far superior Windows 2000 and XP.
????

I thought some of the CLI commands in XP & 2K were considerably more flexible etc. than in DOS or even W98.

Got some examples of W98 commands (or even in DOS 6.0) not implemented in XP?
 
Last edited:

Chuck(G)

25k Member
Joined
Jan 11, 2007
Messages
40,853
Location
Pacific Northwest, USA
Does any DOS CLI have the extended XP... options? A huge number are really really useful. Right now, when working in DOS or Win9x, I use CENVI. Extended command syntax would be nice.
 

MikeS

Veteran Member
Joined
Dec 23, 2005
Messages
7,510
Location
Toronto ON Canada
Does any DOS CLI have the extended XP... options? A huge number are really really useful. Right now, when working in DOS or Win9x, I use CENVI. Extended command syntax would be nice.
Yeah, I like XP CMD; haven't even learned all the new stuff yet.
What's CENVI?
 

Chuck(G)

25k Member
Joined
Jan 11, 2007
Messages
40,853
Location
Pacific Northwest, USA
CEVI is an all-but forgotten utility that allows you to write "C"-like shell scripts in your .BAT files (there's also a Win32 version). DOS Version, Win32 version. A hugely useful and much under-appreciated utility.

Code:
// Struct.cmm - Sample to use STRUCT.LIB
// ver.1

#include <Struct.lib>

Dinner = InitStructArray( "Name", "Entree", "Drink", "Price", NULL,
                          "Paul", "Lasagna", "Orange Juice", 8.95,
                          "Ann Marie", "Chile Relleno", "Cola", 6.67,
                          "Fido", "Bone", "Toilet water", 0.07 );

GuestCount = 1 + GetArraySpan(Dinner);
printf("\nWe had %d dinner guests.  Their dinners were:\n",GuestCount);
for ( i = 0; i < GuestCount; i++ ) {
   printf("\n  Guest Name: %s\n",Dinner[i].Name);
   printf("  Entree: %s\n",Dinner[i].Entree);
   printf("  Drink: %s\n",Dinner[i].Drink);
   printf("  Price: $%.2f\n",Dinner[i].Price);
}
 
Last edited:
Top