Discussion:
small memory model
(too old to reply)
muta...@gmail.com
2022-04-17 04:47:51 UTC
Permalink
Is there any reason why small memory model can't
be used to make a .com file?

Thanks. Paul.
Steve
2022-04-17 12:16:11 UTC
Permalink
Post by ***@gmail.com
Is there any reason why small memory model can't
be used to make a .com file?
Thanks. Paul.
Hi,

A *.COM file is a single segment containing all code,
data, and stack. This is the TINY memory model. The
SMALL model allows for separate code and data segments.
Therefore making a *.COM file would require non-standard
processing to eliminate, or combine, the separate code,
data, and stack segments.

Regards,

Steve N.
muta...@gmail.com
2022-04-17 17:23:37 UTC
Permalink
Post by Steve
Post by ***@gmail.com
Is there any reason why small memory model can't
be used to make a .com file?
A *.COM file is a single segment containing all code,
data, and stack. This is the TINY memory model. The
SMALL model allows for separate code and data segments.
Therefore making a *.COM file would require non-standard
processing to eliminate, or combine, the separate code,
data, and stack segments.
Why is it necessary to eliminate the separate code,
data and stack segments? These are located at
fixed, consecutive locations in the executable. Why
can't the startup code just set ds and ss to those
fixed offsets from cs?

It seems to me that if the above is done, the .com file
would still be able to be loaded anywhere in memory,
and allow 64k code, 64k data and 64k stack.

I'm not sure what startup code would be required to
set ds and ss correctly though.

BFN. Paul.
muta...@gmail.com
2022-04-17 17:52:45 UTC
Permalink
Post by ***@gmail.com
data and stack segments? These are located at
fixed, consecutive locations in the executable. Why
can't the startup code just set ds and ss to those
fixed offsets from cs?
I guess this is a simple form of self-relocation, and
any memory model can be used to produce a .com
file so long as you do your own relocation?

BFN. Paul.
Joe Monk
2022-04-17 19:33:36 UTC
Permalink
Post by ***@gmail.com
Why is it necessary to eliminate the separate code,
data and stack segments? These are located at
fixed, consecutive locations in the executable. Why
can't the startup code just set ds and ss to those
fixed offsets from cs?
It seems to me that if the above is done, the .com file
would still be able to be loaded anywhere in memory,
and allow 64k code, 64k data and 64k stack.
The COM format is the original binary executable format used in CP/M (including SCP and MSX-DOS) as well as DOS. It is very simple; it has no header (with the exception of CP/M 3 files), and contains no standard metadata, only code and data. This simplicity exacts a price: the binary has a maximum size of 65,280 (FF00h) bytes (256 bytes short of 64 KB) and stores all its code and data in one segment.

Since it lacks relocation information, it is loaded by the operating system at a pre-set address, at offset 0100h immediately following the PSP, where it is executed (hence the limitation of the executable's size): the entry point is fixed at 0100h This was not an issue on 8-bit machines since they can address 64k of memory max, but 16-bit machines have a much larger address space, which is why the format fell out of use.

In the Intel 8080 CPU architecture, only 65,536 bytes of memory could be addressed (address range 0000h to FFFFh). Under CP/M, the first 256 bytes of this memory, from 0000h to 00FFh were reserved for system use by the zero page, and any user program had to be loaded at exactly 0100h to be executed. COM files fit this model perfectly. Before the introduction of MP/M and Concurrent CP/M, there was no possibility of running more than one program or command at a time: the program loaded at 0100h was run, and no other.

https://en.wikipedia.org/wiki/COM_file

Joe
s***@yahoo.com
2022-04-17 19:37:22 UTC
Permalink
Post by ***@gmail.com
Is there any reason why small memory model can't
be used to make a .com file?
Thanks. Paul.
No there isn't. However CMD.EXE starting around Win8 won't load it if it is > 64k.
Prior to that CMD.EXE would, as would all the pcDOS's as the Loader would load the entire file size.
I experimented with doing such circa Win 97.

The .cseg must come first, with the code ORG'ed to 0100h. The reason is the Loader prepends a 0100h
Program Segment Prefix, even for .com files prior to jumping to 0100h to start the execution.

This begs the question of what tools to use. I used NASM and it has the directives to make life easier to
do a couple of things.

o align 16, db 00h, placed at the last point in each segment to make them and even paragraph in length.
This is done to figure a segments length, evenly,
;;---------------------------------------------------55
;; End Code Segment
;;---------------------------------------------------55
[SECTION .cseg]
align 16, db 0CCh
cmd_cend:

codelength equ (cmd_cend - cmd_cstart) >> 4
codemin equ codelength

So that this works...

;;
%IF pcDos
ORG 100h
[SECTION .cseg] ;; initial
%ELSE
[SECTION .cseg vstart=0 align=16]
%ENDIF
;;---------------------------------------------------55
cmd_cstart:
;;--- setup runtime segment registers from current CS
;; Note: this assumes real mode contiguous binary.

mov bx,CS
add bx,codemin ;;segm_sz of code + CS = DSEG

So CS plus its length in 'segments' so to speak, now is the segment number of the next segment, DS.

%IF pcDos
add bx,10h ;; adj for 0100h orging
%ENDIF
mov DS,bx
add bx,datamin ;; + segm_sz data = ESEG
%IF pcDos
add bx,10h
%ENDIF
mov ES,bx
add bx,extramin ;; + segm_sz extra = SSEG
%IF pcDos
add bx,10h
%ENDIF
mov SS,bx
mov sp,stack_sp ;;offset in SSEG

main:
call START
jmp alldone
{START code block}
. . .
;;---exit program---

alldone: ;;return to here, exit.

;; do dos exit in this version...

%IF pcDos
mov ax,4C00h
int 21h
%ELSE ;; binary exit thru RomBios.
mov ah,0
int 16h ;;pause until keypress.
int 19h ;;reboot.
%ENDIF


;;---------------------------------------------------55
;; End Code Segment
;;---------------------------------------------------55
[SECTION .cseg]
align 16, db 0CCh
cmd_cend:

codelength equ (cmd_cend - cmd_cstart) >> 4
codemin equ codelength

;;----EO CSeg--------

;;---------------------------------------------------55
;; Data Ends
;;---------------------------------------------------55

[SECTION .dseg] ;;
align 16,db 0F6h

cmd_dend:
datalength equ (cmd_dend - cmd_dstart) >> 4
datamin equ datalength

;;----EO DSeg--------

;;---------------------------------------------------55
;; Extra Ends
;;---------------------------------------------------55
[SECTION .eseg]
cmd_eend:

extralength equ (cmd_eend - cmd_estart) >> 4
extramin equ extralength

;;--- EO ESeg ---

;;---------------------------------------------------55
;; Stack Ends
;;---------------------------------------------------55

[SECTION .sseg]
align 16, db 0CCh
cmd_send:

stack_sp equ (cmd_send - cmd_sstart)
stacklength equ (cmd_send - cmd_sstart) >> 4
stackmin equ stacklength

;;----EO SSeg--------

(rough idea, not final running code ~~ .eseg looks suspect from what I remember)

..an ex. make file for nasm

nasm -@ test.mak
-f bin
-l diskview.lst
-o diskview.bin
diskview.nsm

..Rename the *.bin to *.com

hth,

Steve
muta...@gmail.com
2022-04-17 22:17:37 UTC
Permalink
Post by s***@yahoo.com
Post by ***@gmail.com
Is there any reason why small memory model can't
be used to make a .com file?
No there isn't.
Thanks for confirming that.
Post by s***@yahoo.com
However CMD.EXE starting around Win8 won't load it if it is > 64k.
Prior to that CMD.EXE would, as would all the pcDOS's as the Loader would load the entire file size.
I experimented with doing such circa Win 97.
Thanks for the info. In my case I want the .com file
to be a boot loader. I wish to use SubC which produces
small memory model and was wondering what restriction
that caused compared with tiny.

Thanks for showing the code, but I think there is an issue
with it.
Post by s***@yahoo.com
%IF pcDos
add bx,10h ;; adj for 0100h orging
%ENDIF
mov DS,bx
add bx,datamin ;; + segm_sz data = ESEG
%IF pcDos
add bx,10h
%ENDIF
I don't think you want this add of 10h. You have
already done that once. You don't want to do it
again.
Post by s***@yahoo.com
mov ES,bx
add bx,extramin ;; + segm_sz extra = SSEG
%IF pcDos
add bx,10h
%ENDIF
Ditto.
Post by s***@yahoo.com
mov SS,bx
mov sp,stack_sp ;;offset in SSEG
BFN. Paul.
wolfgang kern
2022-04-18 11:32:01 UTC
Permalink
On 18/04/2022 00:17, ***@gmail.com wrote:
...
Post by ***@gmail.com
Thanks for the info. In my case I want the .com file
to be a boot loader. I wish to use SubC which produces
small memory model and was wondering what restriction
that caused compared with tiny.
If you want it less restricted then make it boot.bin
instead of .COM (not sure your beloved C know that).
__
wolfgang
s***@yahoo.com
2022-04-18 15:40:33 UTC
Permalink
Post by ***@gmail.com
Post by s***@yahoo.com
Post by ***@gmail.com
Is there any reason why small memory model can't
be used to make a .com file?
No there isn't.
Thanks for confirming that.
Post by s***@yahoo.com
However CMD.EXE starting around Win8 won't load it if it is > 64k.
Prior to that CMD.EXE would, as would all the pcDOS's as the Loader would load the entire file size.
I experimented with doing such circa Win 97.
Thanks for the info. In my case I want the .com file
to be a boot loader. I wish to use SubC which produces
small memory model and was wondering what restriction
that caused compared with tiny.
A C Compiler targeting DOS would likely target for .exe in its asm output meaning separate CS, DS=ES
and SS=DS. Since SubC outputs tasm syntax, AIUI, look to tasm docs as to segment restrictions.
Tiny model for .com would mean CS=DS=ES=SS, and a total size of 64k. Tasm probably has a directive
for .com production, so maybe only a simple edit of SubC output of tasm is needed.

https://www.t3x.org/subc/README-current.html
"
SUPPORTED SYSTEMS

SubC generates code for GAS, the GNU assembler (except for the
DOS version, which emits TASM-style syntax). It targets the
following processors and operating systems:

FreeBSD 386* armv6* x86-64
Linux 386* - x86-64*
NetBSD 386* - x86-64*
OpenBSD 386% - -
Windows/MinGW 386* - -
Darwin - - x86-64%(/)
DOS 8086(/)

% uses the syscall layer of the host libc
* untested
! experimental
(/) broken

Platforms tagged "untested" are not regularly tested by myself
and are therefore subject to potential bit rot. You can help
me improve SubC by running "make tests" on an "untested"
platform and let me know about the results.

Platforms using the system's libc as a thin system call layer
often cause build/stability problems due to the omnipresence of
the GNU libc, which is not "thin" at all. Expect trouble on
those systems!

Platforms tagged "broken" currently will not compile or run
properly for some reason. See the Todo file for details.

The DOS version brings its own toolchain, which can be found in
the s86/ directory, so no pre-existing DOS assembler or linker
is required to compile SubC programs on DOS.

Porting SubC to other 32-bit or 64-bit platforms should be
quite straight-forward. See the file "Porting" and/or the book
for a general road map.
"
So TASM syntax. ? but 'broken'?? You probably know about what is going on.
Are you building your own toolchain as well?

AIR, nasm supports 'tasm' syntax, if that path might help.

I almost exclusively program, for fun, in nasm using the -f bin output to a binary file.
That form of format is the most versatile in regards to managing segments.

Since the dos form of SubC has:
void cgprelude(void) { gen(".model small"); }
~as a default, what do TASM docs say about .model tiny?

Steve
Post by ***@gmail.com
BFN. Paul.
Kerr-Mudd, John
2022-04-18 15:57:09 UTC
Permalink
On Mon, 18 Apr 2022 08:40:33 -0700 (PDT)
"***@yahoo.com" <***@yahoo.com> wrote:

[]
Post by s***@yahoo.com
I almost exclusively program, for fun, in nasm using the -f bin output to a binary file.
I had to look this up; it's the default, so I do too!
Post by s***@yahoo.com
That form of format is the most versatile in regards to managing segments.
IAWTP

[]
--
Bah, and indeed Humbug.
Loading...