I'm trying to use NASM (version 2.16.02rc2) with its -f obj (OMF) output format and my version of WarpLink (wl.exe in the 2024-08-01 current build, renamed to warplink.exe, from the most recent revision in this repo) to assemble a DOS MZ executable.
However, it appears that this combination of assembler and linker lead to deleting "uninitialised" (nobits) space at the end of the executable image. I don't want this in this case because I want to add a section ("LAST") that only causes the end of the (initialised) image to be aligned on a paragraph (= 16 byte) boundary. Unfortunately if I just add the section as in section LAST align=16 it appears that albeit the section is aligned, its alignment data is considered uninitialised and deleted from the actual executable image.
In the below test case I used x2b2.com (from the 2024-11-20 current release from the most recent revision in this repo) to extract the executable image from the MZ .exe file and rather than the expected 16 bytes it is only 3 bytes in size.
test.asm source:
section START align=1
nop
nop
nop
section LAST align=16
group GROUP START LAST
mak.sh source, using NASM, dosemu2, WarpLink, and x2b2:
#! /bin/bash
nasm -fobj test.asm -l test.lst -o test.obj
dosemu -dumb -quiet -q -K "$PWD" -E "warplink /mx test.obj,test.exe,test.map;"
dosemu -dumb -quiet -q -K "$PWD" -E "x2b2 test.exe test.bin"
Running the test case:
20241205$ cat test.asm
section START align=1
nop
nop
nop
section LAST align=16
group GROUP START LAST
20241205$ cat mak.sh
#! /bin/bash
nasm -fobj test.asm -l test.lst -o test.obj
dosemu -dumb -quiet -q -K "$PWD" -E "warplink /mx test.obj,test.exe,test.map;"
dosemu -dumb -quiet -q -K "$PWD" -E "x2b2 test.exe test.bin"
20241205$ ./mak.sh
About to Execute : warplink /mx test.obj,test.exe,test.map;
WarpLink release 0 by ecm (2024 August), Michael Devore (1989-1993).
Public Domain software, all copyrights surrendered.
Warning in TEST.EXE
Problem: No stack segment was found for the EXE file.
Solution: This is possibly an error in your program.
An EXE file, unlike a COM file, must internally setup
its own stack if it has no stack segment. To create a
COM file, use the /c option of WarpLink.
Total number of warnings: 1
EXE load image size: 001K
About to Execute : x2b2 test.exe test.bin
X2B2 ecm release 1 - Public Domain Software by Henry T. Nettles
Input File ==> "test.exe" Output File ==> "test.bin"
Code Size = 3 Code Start = 512 Initial IP = 0
Size of output file = 3
20241205$
test.map result:
PROGRAM: TEST.EXE
DATE: 12/05/24
TIME: 02:51 pm
Start Stop Length Name Class
00000H 00002H 00003H START
00010H 00010H 00000H LAST
Origin Group
0000:0 GROUP
Detailed Segment Map
Name Ovl# Address Length Align Combine Class Group Module File
START 0000:0000 0003h BYTE PUBLIC GROUP TEST.ASM TEST.OBJ
LAST 0001:0000 0000h PARA PUBLIC GROUP TEST.ASM TEST.OBJ
Address Status Symbol Name
Program entry point at 0000:0000
Is there a way to emit the alignment, but no further initialised data in the LAST section?
Edited to add: Jester suggested in a comment:
Does it have to be a section? Wouldn't adding an
align 16at the end of your code work for you?
It has to be a section because there may actually be any number of "mid" sections and I don't want to set align=16 for any of the mid sections. Using align 16 at the end of a section (here: the last of the mid sections) will either do sectalign (forcing that mid section to have an alignment of 16) or if we sectalign off then the align 16 will only operate in the (unaligned) mid section and not align to the whole image boundary. Here's two more examples showing this:
20241205$ cat test2.asm
section START align=1
nop
nop
nop
section MID align=1
ds
es
ss
cs
align 16
group GROUP START MID
20241205$ ./mak2.sh
About to Execute : warplink /mx test2.obj,test2.exe,test2.map;
WarpLink release 0 by ecm (2024 August), Michael Devore (1989-1993).
Public Domain software, all copyrights surrendered.
Warning in TEST2.EXE
Problem: No stack segment was found for the EXE file.
Solution: This is possibly an error in your program.
An EXE file, unlike a COM file, must internally setup
its own stack if it has no stack segment. To create a
COM file, use the /c option of WarpLink.
Total number of warnings: 1
EXE load image size: 001K
About to Execute : x2b2 test2.exe test2.bin
X2B2 ecm release 1 - Public Domain Software by Henry T. Nettles
Input File ==> "test2.exe" Output File ==> "test2.bin"
Code Size = 32 Code Start = 512 Initial IP = 0
Size of output file = 32
20241205$
In the test2.bin example, the mid section was sectaligned to be paragraph aligned itself, introducing unwanted alignment between the content of START and MID. Desired output, as before, would be a 16-byte test2.bin output file.
20241205$ cat test3.asm
section START align=1
nop
nop
nop
section MID align=1
ds
es
ss
cs
sectalign off
align 16
group GROUP START MID
20241205$ ./mak3.sh
About to Execute : warplink /mx test3.obj,test3.exe,test3.map;
WarpLink release 0 by ecm (2024 August), Michael Devore (1989-1993).
Public Domain software, all copyrights surrendered.
Warning in TEST3.EXE
Problem: No stack segment was found for the EXE file.
Solution: This is possibly an error in your program.
An EXE file, unlike a COM file, must internally setup
its own stack if it has no stack segment. To create a
COM file, use the /c option of WarpLink.
Total number of warnings: 1
EXE load image size: 001K
About to Execute : x2b2 test3.exe test3.bin
X2B2 ecm release 1 - Public Domain Software by Henry T. Nettles
Input File ==> "test3.exe" Output File ==> "test3.bin"
Code Size = 19 Code Start = 512 Initial IP = 0
Size of output file = 19
20241205$
In the test3.bin example we used sectalign off but this means the align 16 is local to the MID section and doesn't align to the image level paragraph boundary any longer. Same as the two other examples I want test3.bin to be 16 bytes in size.
I adapted WarpLink in a new revision so it will emit alignment before a section named starting with WLEMITALIGN (regardless group or class), even if the section is empty. This is included in the release 4 build of today.
Here's a test case. As before, I want DATA as an unaligned mid-section, and to add an empty last section but with its alignment written to the executable file. The last section is now named with a WLEMITALIGN prefix to activate the new feature.
C:\>type testlink.asm
section CODE
mov ax, 4C00h
int 21h
resb 16
section DATA align=1
db 26h
section WLEMITALIGNED align=16
section STACK stack
resb 512
C:\>testlink.bat
C:\>ldebug /t /p wl /i /mx testlink.obj,testlink.exe,testlink.map;
-g
WarpLink release 4 by ecm (2025 September), Michael Devore (1989-1993).
Public Domain software, all copyrights surrendered.
*** Start of pass 1 on object modules
*** Processing file: TESTLINK.OBJ
*** End of pass 1 on object modules
*** Start of pass 1 on library modules
*** End of pass 1 on library modules
*** Start of pass 2 on object modules
*** Processing file: TESTLINK.OBJ
*** End of pass 2 on object modules
*** Start of pass 2 on library modules
*** End of pass 2 on library modules
*** Begin writing file(s)
*** End writing file(s)
EXE load image size: 001K
Program terminated normally (0000)
-q
C:\>type testlink.map
PROGRAM: TESTLINK.EXE
DATE: 2025-09-20
TIME: 00:10
Start Stop Length Name Class
00000H 00014H 00015H CODE
00015H 00015H 00001H DATA
00020H 00020H 00000H WLEMITALIGNED
00020H 0021FH 00200H STACK
Detailed Segment Map
Name Ovl# Address Length Align Combine Class Group Module File
CODE 0000:0000 0015h BYTE PUBLIC TESTLINK.ASM TESTLINK.OBJ
DATA 0001:0005 0001h BYTE PUBLIC TESTLINK.ASM TESTLINK.OBJ
WLEMITALIGNED 0002:0000 0000h PARA PUBLIC TESTLINK.ASM TESTLINK.OBJ
STACK 0002:0000 0200h BYTE STACK TESTLINK.ASM TESTLINK.OBJ
Address Status Symbol Name
Program entry point at 0000:0000
Executable header size 00200h
Executable initialised image size 00020h
Executable total image size 00220h
C:\>