我正在尝试根据NASM manual中的示例汇总并链接以下程序(.EXE
,而不是.COM
):
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:
我使用以下命令进行汇编(在stdout上不生成任何内容,但生成test.obj
):
nasm -Wall -f obj test.asm
并链接以下命令(这是OpenWatcom 1.9 WLINK):
wlink name test.exe format dos file test.obj
这给了我以下输出(包括警告):
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
手册说明:
上面的代码声明了一个包含64字节未初始化堆栈空间的堆栈段,并在其顶部指向“stacktop”。指令段堆栈栈定义了一个名为`stack`的段,也是一个类型为`STACK`的段。后者对于程序的正确运行不是必需的,但是如果程序没有“STACK”类型的段,则链接器可能会发出警告或错误。
我错过了什么?
答案 0 :(得分:2)
在NASM代码中,您需要将堆栈段标记为具有一类堆栈。
此外,DOS将在程序启动之前为您加载SS和SP。
最后,64字节的堆栈有点太少了。中断服务程序使用当前堆栈,如果它太小,它们将覆盖附近的一些代码或数据。
这就是你解决它的方法:
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: