Welcome to MSDN Blogs Sign in | Join | Help

Why couldn't you have more than one instance of a 16-bit multi-DS program?

Recall that the HINSTANCE identified a set of variables. This causes a bit of a problem if your program has multiple data segments; in other words, multiple sets of variables. In such a program, the code would load the data segment of whatever variable it needed each time it needed to access a variable from a different segment.

This was no problem at all for a DLL, since 16-bit DLLs were single-instance. Go ahead, load your selectors whenever you want. Since there's only one copy of each data segment, you can just use them in your code and let the loader fix them up. No matter which processes calls your DLL, you're still good.

But if you are doing this in a program, you run into trouble once the user runs a second copy of the program. All you get is an HINSTANCE to pass to MakeProcInstance (or to infer from your stack selector). In other words, you get one set of variables. If your program uses multiple sets of variables, you don't have a way to access those other variables, and the operating system has no way of telling you where they are.

Now, a sufficiently clever compiler could work around this failure of mathematics. It could store the selectors of the extra data segments into the data segment specified by the HINSTANCE. When the program needed to access a variable from another data segment, it could access them by loading the appropriate selector from the stack segment register (since SS == DS). I don't know whether anybody actually bothered to write a compiler that did this.

Not that writing one today will win you any accolades since nobody writes 16-bit Windows programs any more. It's one of those things that may have been a neat idea back in its day but today will just get you quizzical looks. Think of it as the computer version of inventing a higher-capacity eight-track cartridge.

Published Friday, February 08, 2008 7:00 AM by oldnewthing
Filed under:

Comments

# re: Why couldn't you have more than one instance of a 16-bit multi-DS program?

Friday, February 08, 2008 1:10 PM by Matt Green

Every time I read one of these posts I get the feeling that 32-bit programming is far more sane than 16-bit programming was. Then again, we really just have complexities of a different sort. Resource consumption just isn't as big of a factor in programming nowadays, and articles like this seem almost quaint with that mindset.

# re: Why couldn't you have more than one instance of a 16-bit multi-DS program?

Friday, February 08, 2008 3:01 PM by mh

Mmmmmm, bringing back hazy memories of such horrors as segments and offsets, different memory models, and how *everybody* on my course in college managed to write "the C program that rebooted your PC" within a week of each other (and all in a totally different way, of course).  Makes one realise and appreciate how good we actually do have it these days.

Love these articles, keep it up!

# re: Why couldn't you have more than one instance of a 16-bit multi-DS program?

Friday, February 08, 2008 3:18 PM by Yuhong Bao

The fundmental problem here was that the code segments was shared across multiple instances, but the data segments were not, and the way the fixups in NE work means that the selectors were an immediate instead of being stored in a variable in the data segment. OS/2 did not have this problem because of separate process address spaces.

# re: Why couldn't you have more than one instance of a 16-bit multi-DS program?

Friday, February 08, 2008 3:30 PM by Tyler

Some day in the not so distant future, we'll all be laughing about how constrained for address space 32-bit processes were.

I apologize for being off-topic, Raymond, but how about an article on (the evils of) code/dll injection, if there is such a thing as a way to do it 'safely' for arbitrary processes?

# re: Why couldn't you have more than one instance of a 16-bit multi-DS program?

Friday, February 08, 2008 5:01 PM by Peter Ritchie

@Matt: "resource consumption just isn't a bit of a factor in programming nowadays".  That's a fallacy that bites many a designer.  I've dealt with designers that had that attitude and did things like create windows with hundreds of controls on them.  When deployed these applications caused system-wide instability and the designer couldn't figure out why.  There are still aspects of development on Windows, even 32-bit, where you must think before you write code.  The problem with the hundreds of controls per window is that Windows has a limited number of system-wide GDI handles (apologies for not referencing one of Raymond's posts on the topic if he's posted about it before).  And, to a certain extent you even have that with memory in 32-bit Windows.  As applications are using more and more memory people don't realized that an application is dealing with a maximum of a 2Gb heap (by default), despite having 4GB of RAM and lots of hard-drive space.  Going 64-bit alleviates that memory issue (trading it for a different limit) much the same as going from 16- to 32-bit.

The issues are different but designers still have to account for system limits when designing good software, it's always best to design as if everything you use is a limited resource.

# re: Why couldn't you have more than one instance of a 16-bit multi-DS program?

Friday, February 08, 2008 6:15 PM by mh

It's always been my experience that the more you increase limits, the more people will find creative ways to fill them up.  The biggest advantage of 32 bit was a flat address space (I may be wrong, but protected mode was just a processor feature that happened to coincide with 32 bit).

# re: Why couldn't you have more than one instance of a 16-bit multi-DS program?

Friday, February 08, 2008 8:41 PM by oj

...do I even need to say it?!

Come on, Raymond. Instead of going into such detail about obsolete old Win16 stuff all the time, why not use your obviously COPIOUS amounts of free (work) time, and your extensive knowledge of the inner workings of Win32, to actually give out some useful insights, that might actually help us 'mere mortals' work around your team's various past gaffs so we can write sligthly-less-sucky Windows apps?

Between these kinds of entries and the 'hilarious personal anecdotes', there is very little value coming out of this blog imho, given its supposed theme.

3.0

# re: Why couldn't you have more than one instance of a 16-bit multi-DS program?

Friday, February 08, 2008 9:08 PM by colin

Then stop reading it, geez!  He's not your personal problem solver.

# re: Why couldn't you have more than one instance of a 16-bit multi-DS program?

Friday, February 08, 2008 10:35 PM by Ulric

Funny, I don't remember any of this multiple-data segment thing.  I was always using the Large memory model, I believe.   Coincidently We were trying to remember last week at work what the various models did (tiny, small, medium, large, huge!).

Anyway, a search got me this helpful KB article, which mentions the multiple-DS issue!

Using Large Memory Model, Microsoft C/C++, & Windows 3.1

http://support.microsoft.com/kb/90294

# re: Why couldn't you have more than one instance of a 16-bit multi-DS program?

Friday, February 08, 2008 11:41 PM by Triangle

"...and your extensive knowledge of the inner workings of Win32, to actually give out some useful insights, that might actually help us 'mere mortals' work around your team's various past gaffs so we can write sligthly-less-sucky Windows apps?"

Ahh - But there is value in these posts!

The situations Mr. Chen is describing can apply to any kind of system that shares data in a similiar fashion. It's simply a manner of noticing a pattern repeat itself. As programmers, we're naturally apt at finding such patterns.

"I've dealt with designers that had that attitude and did things like create windows with hundreds of controls on them.  When deployed these applications caused system-wide instability and the designer couldn't figure out why."

Is it just me, or would you think that with a system so _vastly_ used, and designed to be used in this way, Windows UI management code would be optimized enough to be able to handle this? 2GB is _alot_ of memory, when properly utilized.

# re: Why couldn't you have more than one instance of a 16-bit multi-DS program?

Saturday, February 09, 2008 5:55 AM by SuperKoko

mh wrote:

"It's always been my experience that the more you increase limits, the more people will find creative ways to fill them up."

Some programmers don't understand that if I buy a new computer, I want it to treat larger data sets, not smaller ones.

With a 80486 DX2 66 with 4 megabytes of RAM, it's possible to open large text files with Emacs (e.g. 50 megabytes).

With extremely powerful computers, most modern text editors (including Microsoft Word) painfully open 10 megabytes files!

mh wrote:

"The biggest advantage of 32 bit was a flat address space (I may be wrong, but protected mode was just a processor feature that happened to coincide with 32 bit)."

Yeah, you're wrong. The 80286 CPU had a 16 bits protected mode, with a 16MiB physical addressing space. The model wasn't flat, of course.

Windows 3.x in standard mode uses it.

Triangle wrote:

"

Windows UI management code would be optimized enough to be able to handle this? 2GB is _alot_ of memory, when properly utilized.

"

No. Read these entries.

http://blogs.msdn.com/oldnewthing/archive/2007/07/16/3885472.aspx

http://blogs.msdn.com/oldnewthing/archive/2007/07/17/3903614.aspx

http://blogs.msdn.com/oldnewthing/archive/2007/07/18/3926581.aspx

http://blogs.msdn.com/oldnewthing/archive/2005/03/15/395866.aspx

http://support.microsoft.com/?scid=126962

# re: Why couldn't you have more than one instance of a 16-bit multi-DS program?

Saturday, February 09, 2008 6:11 AM by SuperKoko

@oj: Come on, it's a blog not a reference manual or help desk.

Raymond shares what he likes. History blog entries are especially interesting because

oj wrote:

"

Between these kinds of entries and the 'hilarious personal anecdotes', there is very little value coming out of this blog imho, given its supposed theme.

"

What's the part of "The Old New Thing" title that you didn't understand?

Many entries give a look at old things, with a new eye, in a modern world. (Well, that's an interpretation that's worth another one).

Of course, it's also a blog on which Raymond dumps what he found funny, valuable or just want to share.

If you find there's very little value coming there, why do you come?

I find these entries valuable because there's very little data on the Web about 16 bits Windows.

# re: Why couldn't you have more than one instance of a 16-bit multi-DS program?

Saturday, February 09, 2008 12:06 PM by Triangle

SuperKoko: All you've established is that the current system is inefficient. Obviously it won't improve without any change. And don't forget that windows 64-bit no longer runs DOS programs, so 16 bit limits don't even apply there.

# re: Why couldn't you have more than one instance of a 16-bit multi-DS program?

Saturday, February 09, 2008 4:43 PM by SuperKoko

"All you've established is that the current system is inefficient. "

Which is exactly what I meant.

"

Obviously it won't improve without any change. And don't forget that windows 64-bit no longer runs DOS programs, so 16 bit limits don't even apply there.

"

Which doesn't change my point.

I just explained why Windows aren't a cheap resource in Win32, not in Win64.

AFAIK, WinFX doesn't have these limitations at all.

# re: Why couldn't you have more than one instance of a 16-bit multi-DS program?

Sunday, February 10, 2008 7:38 AM by Ross Bemrose

oj:

Given that the title of both the blog (The Old New Thing) and book (The Old New Thing: Practical Development Throughout the Evolution of Windows), I think it's fairly clear that Windows history is going to be brought up... a lot.

# re: Why couldn't you have more than one instance of a 16-bit multi-DS program?

Monday, February 11, 2008 9:14 AM by pk

You've got a lot of nerve, Mr. Chen.  How dare you post to your blog without consulting me on whether I find your topics interesting!

# re: Why couldn't you have more than one instance of a 16-bit multi-DS program?

Monday, February 11, 2008 10:04 AM by David Walker

Those who don't understand history are doomed to repeat it, or something like that.  To coin a phrase.

# re: Why couldn't you have more than one instance of a 16-bit multi-DS program?

Monday, February 11, 2008 10:30 AM by mschaef

Ulric wrote: "Coincidently We were trying to remember last week at work what the various models did (tiny, small, medium, large, huge!)."

It's been a while, but here's how I remember it. Segmented pointers typically fell into three categories: near, far, and huge. A near pointer was only an offset, and had an implied segment. A far pointer was a segment:offset pair, and a huge pointer was a segment:offset pair that was treated with special code to give the illusion of a flat address space. Given that, the models broke down like so:

Tiny = All pointers are near pointers to a shared code and data segment. This is the memory model that was used to compile .COM files, as opposed to .EXE files.

Small = All pointers are near pointers, but there are separate segments for code and data.

Medium = All data pointers are near pointers to one data segment.  Multiple code segments are allowed, so code pointers are far. Typically, each compilation unit got its own segment.

Large = Medium, plus far data pointers by default, so there could be multiple data segments.

Huge = Large, but data pointers are huge by default, giving a slow illusion of a flat address space.

Notably, the memory model of a program mainly specified the default properties. For example, it was still possible to explicitly declare a far or huge pointer in a medium model program. There were also differences in standard libraries. Switching from medium model (1 data segment) to large (multiple) typically required a different implementation of malloc/free that could handle far pointers.

My recollection of huge pointers was that they were mainly a curiosity for easily porting programs from larger machines. If you really wanted fast performance with multiple data segments, you explicitly managed the segments yourself.

# re: Why couldn't you have more than one instance of a 16-bit multi-DS program?

Monday, February 11, 2008 1:10 PM by asdf

I predict the segmented memory model is going to come back into fashion when people complain that all their objects are twice the size on 64-bit platforms. Silly masochistic programmers will manually attempt shrinking pointers and sillier compiler vendors will help them out with syntax sugar instead of working on ways apply these optimizations automatically.

# re: Why couldn't you have more than one instance of a 16-bit multi-DS program?

Tuesday, February 12, 2008 2:12 AM by Gabe

SuperKoko: Have you ever actually *tried* to open a 50MB file in emacs on a 4MB computer?

Back in 1995 I was doing profiling and ended up with log files that got up to 60MB. I tried opening the file in emacs but couldn't because it had a limit of 32MB. If I had changed the limit, though, it would have sat there thrashing while trying to read the whole file into memory before it would ever let me see the first character of it. For the record, vi and Notepad had similar failures.

Word showed me the first page immediately, then slowly chugged through the whole file to paginate it. Why? Because it was originally designed to run in an environment Raymond describes.

# re: Why couldn't you have more than one instance of a 16-bit multi-DS program?

Tuesday, February 12, 2008 10:48 PM by Alex Grigoriev

"Anyway, a search got me this helpful KB article".

I always wonder why MS removes recent articles from KB while leaving such ancient ones?

New Comments to this post are disabled
 
Page view tracker