I'm trying to assemble and link the following program (.EXE
, not .COM
), based on the example in the NASM manual:
segment data
hello: db "hello",13,10,"$"
segment code
..start:
mov ax,data
mov ds,ax
mov ax,stack
mov ss,ax
mov sp,stacktop
mov dx,hello
mov ah,9
int 0x21
mov ax,0x4c00
int 0x21
segment stack stack
resb 64
stacktop:
I assemble with the following command (which produces nothing on stdout, but generates test.obj
):
nasm -Wall -f obj test.asm
and link with the following command (this is OpenWatcom 1.9 WLINK):
wlink name test.exe format dos file test.obj
This gives me the following output (including a warning):
Open Watcom Linker Version 1.9
Portions Copyright (c) 1985-2002 Sybase, Inc. All Rights Reserved.
Source code is available under the Sybase Open Watcom Public License.
See http://www.openwatcom.org/ for details.
loading object files
Warning! W1014: stack segment not found
creating a DOS executable
The manual states:
The above code declares a stack segment containing 64 bytes of uninitialized stack space, and points `stacktop` at the top of it. The directive segment stack stack defines a segment called `stack`, and also of type `STACK`. The latter is not necessary to the correct running of the program, but linkers are likely to issue warnings or errors if your program has no segment of type `STACK`.
What am I missing?
In NASM code you need to mark the stack segment as having a class of stack.
Also, DOS will load SS and SP for you before your program starts.
Finally, 64 bytes of stack is a little too little. Interrupt service routines use the current stack and if it's too small, they will overwrite some code or data nearby.
This is how you fix it:
segment data
hello: db "hello",13,10,"$"
segment code
..start:
mov ax,data
mov ds,ax
; mov ax,stack
; mov ss,ax
; mov sp,stacktop
mov dx,hello
mov ah,9
int 0x21
mov ax,0x4c00
int 0x21
segment stack class=stack
resb 512 ; 64 is too little for interrupts
;stacktop: