Smaller C (was: What does your OS look like?)

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Antti
Member
Member
Posts: 923
Joined: Thu Jul 05, 2012 5:12 am
Location: Finland

Re: Smaller C (was: What does your OS look like?)

Post by Antti »

Hello Alex, I have one suggestion. Look at the MZ header (smlrc16.asm):

Code: Select all

47      section .text
48
49      ; _text_start_: file offset = 0, IP = file offset & 0xFFFF = 0
50      _text_start_:
51      db  "MZ"
..      ...
56      dw  0 ; min RAM needed in paragraphs after the image
57      dw  0 ; max RAM needed in paragraphs after the image
Are you sure you want to use "dw 0" for "max RAM"? I suggest that you use "dw 0xFFFF". If you use zero, your program is loaded as high as possible. I would prefer loading it as low as possible (using "max RAM"0xFFFF).

For example, I made two 1024-byte test programs (writing by hand), with "max RAM" 0x0000 and 0xFFFF. The first one was loaded at 0x9F9F:0x0000 (high) and the latter was loaded at 0x1979:0x0000 (low) on my DR-DOS computer.
alexfru
Member
Member
Posts: 1112
Joined: Tue Mar 04, 2014 5:27 am

Re: Smaller C (was: What does your OS look like?)

Post by alexfru »

Antti wrote:Hello Alex, I have one suggestion. Look at the MZ header (smlrc16.asm):

Code: Select all

47      section .text
48
49      ; _text_start_: file offset = 0, IP = file offset & 0xFFFF = 0
50      _text_start_:
51      db  "MZ"
..      ...
56      dw  0 ; min RAM needed in paragraphs after the image
57      dw  0 ; max RAM needed in paragraphs after the image
Are you sure you want to use "dw 0" for "max RAM"?
I'm sure. Why would I want to allocate more memory than needed when it's easy to avoid it?
Antti wrote:I suggest that you use "dw 0xFFFF".
Why would I want to allocate all of the memory to my program? I see no benefit here. But I can see a potential disadvantage. If my program needs to load and run another program but there's no memory left because all of it has already been allocated to my program, that other program can't be loaded. This is why the linker sets this max number as low as possible. This is why I've reduced the default stack size set by the linker. If I followed your suggestion everywhere, smlrcc wouldn't be able to run smlrc or smlrl.
Antti wrote:If you use zero, your program is loaded as high as possible. I would prefer loading it as low as possible (using "max RAM"0xFFFF).
Oh, so your having an odd (or at least, unjustified) preference is somehow my problem and I should follow your suggestions about it? How quaint.
Antti wrote:For example, I made two 1024-byte test programs (writing by hand), with "max RAM" 0x0000 and 0xFFFF. The first one was loaded at 0x9F9F:0x0000 (high) and the latter was loaded at 0x1979:0x0000 (low) on my DR-DOS computer.
So what? What's your problem here? Do you actually have one? How and why should it be my problem?

Btw, if you care so much about where programs are loaded in your system, have you tried changing the memory allocation strategy in the system (see function 0x5801 of int 0x21)?
Antti
Member
Member
Posts: 923
Joined: Thu Jul 05, 2012 5:12 am
Location: Finland

Re: Smaller C (was: What does your OS look like?)

Post by Antti »

alexfru wrote:Why would I want to allocate more memory than needed when it's easy to avoid it?
You would not waste any memory by loading the program as low as possible.
alexfru wrote:If my program needs to load and run another program but there's no memory left because all of it has already been allocated to my program, that other program can't be loaded.
On DOS, I think it is convenient to use free memory that is above the program than below it.
alexfru wrote:So what? What's your problem here? Do you actually have one? How and why should it be my problem?
I just made a suggestion that I considered to be a much better default setting.
linguofreak
Member
Member
Posts: 510
Joined: Wed Mar 09, 2011 3:55 am

Re: Smaller C (was: What does your OS look like?)

Post by linguofreak »

alexfru wrote:Why would I want to allocate all of the memory to my program?


The general convention with DOS programs is for a program to be loaded low and for all available memory to be allocated to it (as DOS is a single-tasking OS). If a program needs to call another program, or is a TSR, it then explicitly releases the memory it doesn't need.
Oh, so your having an odd (or at least, unjustified) preference is somehow my problem and I should follow your suggestions about it? How quaint.
His preference is justified in that it is the default behavior under DOS. Therefore, a DOS toolchain should default to it.
alexfru
Member
Member
Posts: 1112
Joined: Tue Mar 04, 2014 5:27 am

Re: Smaller C (was: What does your OS look like?)

Post by alexfru »

Antti wrote:
alexfru wrote:Why would I want to allocate more memory than needed when it's easy to avoid it?
You would not waste any memory by loading the program as low as possible.
Right, but manipulating the max field is the wrong way of changing the location where the program gets loaded. The max field's primary purpose is to reserve memory and not to control the program's location (btw, relying on or requiring a particular memory layout is generally a bad idea, there must be strong reasons for doing such odd things). If all of the memory is allocated because of max=0xFFFF, then I can't load and execute subordinate programs using the standard APIs and even if I could, they in turn wouldn't be able to allocate any additional memory using the standard APIs. Setting max=0xFFFF *does* result in an unjustified waste of memory. This field is not a location control.
Antti wrote:
alexfru wrote:If my program needs to load and run another program but there's no memory left because all of it has already been allocated to my program, that other program can't be loaded.
On DOS, I think it is convenient to use free memory that is above the program than below it.
Maybe. Maybe not. Do you have an actual scenario, where one or the other is so much preferable that it must be the only way? Or are you just thinking in some abstract terms and trolling people with your fantasies? Or are you thinking about something completely unrelated here? For example, some people would stack your tech books on the shelf by their size or color, because that's the best they can do it and everything just looks neat that way. :) Except then you can't find your books in this piece of art.
Antti wrote:
alexfru wrote:So what? What's your problem here? Do you actually have one? How and why should it be my problem?
I just made a suggestion that I considered to be a much better default setting.
You just took it out of y... well, you know out of where. You never explained how loading lower is better than loading higher or vice versa. If you said that your RAM was bad at lower addresses, that would be laughable, but nonetheless enough of a reason to even remotely consider lower vs higher locations. But you did not provide any reason or scenario whatsoever to support your claim. And yet somehow your suggestion is "much better". Really? Your suggestion will also break some of properly working code. Again, for no good reason at all.

Sorry, but so far you aren't making much sense.
alexfru
Member
Member
Posts: 1112
Joined: Tue Mar 04, 2014 5:27 am

Re: Smaller C (was: What does your OS look like?)

Post by alexfru »

linguofreak wrote:
alexfru wrote:Why would I want to allocate all of the memory to my program?


The general convention with DOS programs is for a program to be loaded low
Perhaps, but did you see what I'd been told? DRDOS in question appears to be doing the opposite thing. How is that my problem? The OS loads programs wherever it wishes or however it's configured. My .EXE programs have nothing to do with this policy/strategy. This policy/strategy is external to them.
linguofreak wrote:and for all available memory to be allocated to it (as DOS is a single-tasking OS).
I disagree. This is what happens with .COM programs. This is what happens with .EXE programs whose header's max field is sufficiently large. However, I have every right to request less memory allocated to my program than all the remaining RAM. That's what the max field is for. And you can't tell me I'm wrong here.
linguofreak wrote:If a program needs to call another program, or is a TSR, it then explicitly releases the memory it doesn't need.
It's possible to do it that way, but it's not the only way of handling memory and subordinate programs. I see no good reason in allocating more memory than needed to only have to free it later. Looks stupid to me.
linguofreak wrote:
Oh, so your having an odd (or at least, unjustified) preference is somehow my problem and I should follow your suggestions about it? How quaint.
His preference is justified in that it is the default behavior under DOS. Therefore, a DOS toolchain should default to it.
I'm sorry, what are we debating here? (DR)DOS' own behavior? My code has nothing to do with it. Change the OS policy/strategy if you don't like it. It wasn't me who set it.
Antti
Member
Member
Posts: 923
Joined: Thu Jul 05, 2012 5:12 am
Location: Finland

Re: Smaller C (was: What does your OS look like?)

Post by Antti »

You seem to be very sure about this. Forget the DR-DOS, this is for DOS systems in general.

Code: Select all

- PROGRAM 1 ------------------------------------------------------------------
	MZHeader

	Code:
		...
		...
		lea dx, [programSpec]	; ds:dx = program specification
		lea bx, [paramBlock]	; es:bx = parameter block
		mov al, 0x00		; loading and executing
		mov ah, 0x4B		; execute program (DOS call)
		int 0x21

		; This is likely to return error 8, insufficient memory
------------------------------------------------------------------------------


- PROGRAM 2 ------------------------------------------------------------------
	MZHeader

	Code:
		...
		...
		mov bx, SIZE_REQUESTED	; new block size in paragraphs
		mov ax, SEGMENT
		mov es, ax		; segment block to be modified
		mov ah, 0x0A		; modify memory allocation
		int 0x21
		...
		...
		lea dx, [programSpec]	; ds:dx = program specification
		lea bx, [paramBlock]	; es:bx = parameter block
		mov al, 0x00		; loading and executing
		mov ah, 0x4B		; execute program (DOS call)
		int 0x21

		; This is likely to work
------------------------------------------------------------------------------
I did not check the code so it is just pseudo-code. I suggested that loading the program as low as possible is a better option, i.e. using "max RAM" 0xFFFF.
linguofreak
Member
Member
Posts: 510
Joined: Wed Mar 09, 2011 3:55 am

Re: Smaller C (was: What does your OS look like?)

Post by linguofreak »

alexfru wrote:Perhaps, but did you see what I'd been told? DRDOS in question appears to be doing the opposite thing. How is that my problem? The OS loads programs wherever it wishes or however it's configured. My .EXE programs have nothing to do with this policy/strategy. This policy/strategy is external to them.
My initial impression was that Antii was complaining about your compiler using a default header for compiled programs that was an unusual default. On second reading, he seems to be critiquing the header of the compiler executable itself.
alexfru
Member
Member
Posts: 1112
Joined: Tue Mar 04, 2014 5:27 am

Re: Smaller C (was: What does your OS look like?)

Post by alexfru »

Antti wrote:You seem to be very sure about this. Forget the DR-DOS, this is for DOS systems in general.

Code: Select all

...
I did not check the code so it is just pseudo-code. I suggested that loading the program as low as possible is a better option, i.e. using "max RAM" 0xFFFF.
Sorry, I don't see your point. My smlrcc.exe successfully executes smlrc.exe, smlrl.exe and nasm.exe in DOS (specifically, in Windows 98's DOS, Windows XP's command line and some time ago in DosBox (test programs exc.exe and libtest.exe for sure execute themselves in all three)). To me it looks like everything's right from DOS' point of view.
alexfru
Member
Member
Posts: 1112
Joined: Tue Mar 04, 2014 5:27 am

Re: Smaller C (was: What does your OS look like?)

Post by alexfru »

linguofreak wrote:
alexfru wrote:Perhaps, but did you see what I'd been told? DRDOS in question appears to be doing the opposite thing. How is that my problem? The OS loads programs wherever it wishes or however it's configured. My .EXE programs have nothing to do with this policy/strategy. This policy/strategy is external to them.
My initial impression was that Antii was complaining about your compiler using a default header for compiled programs that was an unusual default. On second reading, he seems to be critiquing the header of the compiler executable itself.
smlrc.exe can be compiled for DOS in several different ways. Two of them include using smlrc16.asm and smlrchg.asm, which do contain headers in asm code, just as Antii showed. The other one is compiling with smlrcc/smlrl and using the headers set up and supplied by smlrl. In all three cases the max field of the .exe header is small and does not cover more memory than the .exe actually needs for its data and stack segments.
Antti
Member
Member
Posts: 923
Joined: Thu Jul 05, 2012 5:12 am
Location: Finland

Re: Smaller C (was: What does your OS look like?)

Post by Antti »

linguofreak wrote:On second reading, he seems to be critiquing the header of the compiler executable itself.
It does not matter, I just checked the source code file and saw that "max RAM" = 0. When I made experiments with the "MZ EXE" format I did the same thing at first and I wondered why the common convention is to put "max RAM" = 0xFFFF. Then I noticed that the side effect is that the program is loaded as high as possible.

Even if both ways work, I considered the usual way of loading the program as low as possible more safe, less-surprising and more compatible. That is why I suggested using it. I see no advantages of using "max RAM" = 0.
alexfru
Member
Member
Posts: 1112
Joined: Tue Mar 04, 2014 5:27 am

Re: Smaller C (was: What does your OS look like?)

Post by alexfru »

Antti wrote:Even if both ways work, I considered the usual way of loading the program as low as possible more safe, less-surprising and more compatible.
I have to ask you, if you want to be safe, don't you have to find out where your extra memory (after the executable) ends before you can use it? If you do, is the location important?
alexfru
Member
Member
Posts: 1112
Joined: Tue Mar 04, 2014 5:27 am

Re: Smaller C (was: What does your OS look like?)

Post by alexfru »

Consider the following test program for Smaller C:

Code: Select all

// file: mmlayout.c
// compile: smlrcc -dosh mmlayout.c -o mmlayout.exe
//      or: smlrcc -doss mmlayout.c -o mmlayout.exe
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char* argv[])
{
  char cmd[] = "mmlayout.exe 0";
#ifdef __SMALLER_C_32__
  printf("&main: 0x%08x\n", (unsigned)main);
#else
  printf("&main: 0x%04x:0x%04x\n", __getCS(), (unsigned)main);
#endif
  if (argc <= 1)
  {
    cmd[sizeof cmd - 2] = '5';
    system(cmd);
  }
  else if (argv[1][0] > '1' && argv[1][0] <= '9')
  {
    cmd[sizeof cmd - 2] = argv[1][0] - 1;
    system(cmd);
  }
}
Output in DOSBox:

Code: Select all

C:\mmlayout.exe
&main: 0x00001a20
&main: 0x0000f3d0
&main: 0x0001cdc0
&main: 0x0002a7b0
&main: 0x000381a0
&main: 0x00045b90
Output in Windows XP:

Code: Select all

C:\SMLRC>mmlayout.exe
&main: 0x000054d0
&main: 0x00013180
&main: 0x00020e50
&main: 0x0002eb50
&main: 0x0003c850
&main: 0x0004a550
Is something wrong with that DRDOS then?
Antti
Member
Member
Posts: 923
Joined: Thu Jul 05, 2012 5:12 am
Location: Finland

Re: Smaller C (was: What does your OS look like?)

Post by Antti »

I was a little bit wrong. Only the "max RAM" = 0 is the special case. If you use non-zero values, it should be OK. Look at the screenshot and segment registers (especially CS and SS):
Attachments
dosbox.png
alexfru
Member
Member
Posts: 1112
Joined: Tue Mar 04, 2014 5:27 am

Re: Smaller C (was: What does your OS look like?)

Post by alexfru »

So, to recap...

smlrc16.asm, that you raised concerns about, may be used to compile a 16-bit only version of smlrc.exe using only smlrc.exe and nasm.exe and no other linkers, drivers, etc. Even with max=0 in smlrc16.asm's exe header, neither smlrc.exe itself nor any other executable is anyhow adversely affected. smlrc.exe does not launch any other programs (only smlrcc.exe does).

The exe header in smlrchg.asm and those produced by smlrl.exe have non-zero values in the max field.

Tests in DOSBox and Windows XP show that the DOS version of Smaller C (for which I'm no longer using smlrc16.asm or smlrchg.asm) and DOS .EXEs produced by it function as expected and are loaded at the lowest available addresses first.

IOW, the reported problem is nowhere to be found and the suggestion is invalid.
Post Reply