'Not adding the stack bytes to the .EXE file with MASM 5.0

I'm writing two assembly files for DOS:

hm2.asm:

.8086 
DGROUP group _DATA, STACK  ; Required by MASM 3.0 and 4.0. 
 
; MASM 4.0 doesn't support USE16 (but MASM >=5.0 does). 
_TEXT segment word public 'CODE' 
assume cs:_TEXT, ds:DGROUP, ss:STACK 
main proc 
mov ax, DGROUP  ; Initialize DS. 
mov ds, ax 
mov ah, 9  ; DOS Function call to print a message. 
mov dx, offset message 
int 21h 
mov ax, 4c00h  ; DOS Function call to exit back to DOS. 
int 21h 
main endp 
_TEXT ends 
 
_DATA segment word public 'DATA' 
message db "Hello, World!", 0dh, 0ah, '$' 
_DATA ends 
 
STACK segment para stack 'STACK' 
db 100h dup (?) 
STACK ends 
 
end main 

hm3.asm:

.8086 
.model small 
.stack 100h 
.data 
message db "Hello, World!", 0dh, 0ah, '$' 
.code 
main proc 
mov ax, @data  ; Initialize DS. 
mov ds, ax 
mov ah, 9  ; DOS Function call to print a message. 
mov dx, offset message 
int 21h 
mov ax, 4c00h  ; DOS Function call to exit back to DOS. 
int 21h 
main endp 
end main 

I want these to be identical when compiled by Microsoft Macro Assembler 5.00 masm.exe and then linked to an .EXE file with the corresponding link.exe . However, hm2.exe is about 256 == 100h bytes longer than hm3.exe, because it contains zero-bytes for the STACK. How do I get rid of these zero-bytes without using .model and .stack, thus being compatible with Microsoft Macro Assembler 4.00 and earlier?



Solution 1:[1]

For old-style code (without a .model directive), the STACK segment must be the last for the trailing 00 bytes to be omitted by the linker. Also, the order of _TEXT and _DATA segment determines the order in which they are written to the .exe program output file. The order of segments within the DGROUP group doesn't matter.

For new-style code (with a .model directive, supported from Microsoft Macro Assembler 5.00 and later), the order of .stack, .data and .code directives doesn't matter. the assembler generates the .obj file in the correct order (.code, .data, .stack).

In general, the order of segments within the .asm file propagates to the .obj file, and the linker uses that to decide the order within the final .exe file.

Solution 2:[2]

I found a copy of the MASM 3.00 manual here. On page 3-2 there is an example program that looks like this

 .8086

DATA segment ; Program Data Segment
STRING db "Hello .", 13, 10, "$"
DATA ends

CODE segment ; Program Code Segment
 assume cs :CODE, ds :DATA
START: ; Program Entry Point
 mov ax, seg DATA
 mov ds, ax
 mov dx, offset STRING
 mov ah, 9
 int 21h
 mov ah, 4ch
 int 21h
CODE ends

STACK segment stack ; Program Stack Segment
 assume ss :STACK
 dw 64 dup(?)
STACK ends

 end START

I was able to assemble and link this to an exe of 640 bytes. When I increased the stack size (from 64 to 1024) the exe size didn't change, from which I assume that the linker is not padding out unitialized stack bytes in the image. If you compare the example program to yours, maybe that'll help you figure it out.

Possibly the answer is to remove the DGROUP directive.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 pts
Solution 2 Peter Hull