1

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?

Jack Kelly
  • 18,264
  • 2
  • 56
  • 81

1 Answers1

3

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:
Alexey Frunze
  • 61,140
  • 12
  • 83
  • 180
  • 2
    I'd go as far as to say 4K is barely big enough for a DOS stack now, considering all the garbage drivers that proliferated in DOS's last days along with the complications certain DOS emulators bring. – JimR Mar 25 '12 at 23:41
  • @JimR: I'm glad there are still folks out there who remember this stuff. You've been a big help. – Jack Kelly Apr 04 '12 at 09:00