如果您打算重新打开像_DATA 这样的段,则该段必须与之前声明的段属性匹配。当您使用简化的 DOS 段和 model 指令时,_TEXT 和 _DATA 段的默认值是 WORD 对齐。您已将对齐方式从默认的 WORD 更改为 BYTE,因此收到了您看到的错误。 TASM 5 manual 声明:
段属性非法重定义
SEGMENT 指令重新打开之前定义的段,
并试图赋予它不同的属性。例如:
DATA SEGMENT BYTE PUBLIC
DATA ENDS
DATA SEGMENT PARA ; error, previously had byte alignment
DATA ENDS
如果您重新打开一个细分,您提供的属性必须匹配
完全或完全省略。 如果您不提供任何属性
重新打开段时,将使用旧属性。
你有几个选择。一种是比较简单的一种,就是把代码段中的代码和数据结合起来:
ideal
model tiny
codeseg
startupcode
lea dx,[lpText]
mov ah,9
int 21h
exitcode
lpText: db "Hello, world!$"
end
如果您要组装它,它应该会生成一个大小为 25 字节的程序:
00000100 BA0B01 mov dx,0x10b
00000103 B409 mov ah,0x9
00000105 CD21 int 0x21
00000107 B44C mov ah,0x4c
00000109 CD21 int 0x21
0000010B 48 dec ax
0000010C 656C gs insb
0000010E 6C insb
0000010F 6F outsw
00000110 2C20 sub al,0x20
00000112 776F ja 0x183
00000114 726C jc 0x182
00000116 642124 and [fs:si],sp
另一种方法是不使用model 指令并从头开始声明您自己的段:
ideal
group DGROUP _DATA, _TEXT
segment _TEXT byte 'CODE'
org 100h
ends
segment _DATA byte 'DATA'
ends
segment _DATA
lpText db "Hello, world!$"
ends
segment _TEXT
_start:
lea dx,[lpText] ; or mov dx, offset lptext
mov ah,9
int 21h
ret ; COM programs that use TINY model
; can exit with a RET. DOS places 0000h
; on the stack when program starts. Returning
; to 0000h executes an INT 20h instruction at
; offset 0000h in the PSP
ends
end _start
startupcode 和 exitcode 指令在简化段模型之外不起作用,因此您需要自己生成代码。由于我假设您正在使用tiny 模型生成 DOS COM 程序,因此您可以使用ret 从 DOS 返回,假设您不需要返回错误级别。这减小了程序的大小。不需要设置段寄存器,因为当 DOS 开始运行 COM 程序时,CS=DS=ES=SS 都指向Program Segment Prefix (PSP)。生成的程序如下所示:
00000100 BA0801 mov dx,0x108
00000103 B409 mov ah,0x9
00000105 CD21 int 0x21
00000107 C3 ret
00000108 48 dec ax
00000109 656C gs insb
0000010B 6C insb
0000010C 6F outsw
0000010D 2C20 sub al,0x20
0000010F 776F ja 0x180
00000111 726C jc 0x17f
00000113 642124 and [fs:si],sp
生成的 COM 程序应该是 22 字节的大小。
如果您将之前代码中的 ret 替换为:
mov ah,4ch
int 21h
生成的文件将是 25 字节大小,更重要的是,_DATA 段未在 WORD 边界上对齐:
00000100 BA0B01 mov dx,0x10b
00000103 B409 mov ah,0x9
00000105 CD21 int 0x21
00000107 B44C mov ah,0x4c
00000109 CD21 int 0x21
0000010B 48 dec ax
0000010C 656C gs insb
0000010E 6C insb
0000010F 6F outsw
00000110 2C20 sub al,0x20
00000112 776F ja 0x183
00000114 726C jc 0x182
00000116 642124 and [fs:si],sp