pts*_*pts 3 x86 assembly dos tasm x86-16
我的汇编源代码:
ideal
model tiny
segment _data byte ; TASM doesn't accept it.
ends _data
dataseg
align 1 ; Doesn't decrease the segment alignment.
lpText db "Hello, world!$"
codeseg
startupcode
lea dx,[lpText]
mov ah,9
int 21h
exitcode
end
Run Code Online (Sandbox Code Playgroud)
TASM 5.0 给了我错误段属性非法重新定义其中的行byte
。
如何在理想模式下将数据段更改为字节对齐?
我需要它,因为我不希望在lpText前面生成的 .com 文件中有一个额外的 0 字节。我希望 .com 文件尽可能小。
如果您打算重新打开一个段,_DATA
那么该段必须与之前声明的段属性匹配。当您使用简化的 DOS 段和model
指令时,默认值是_TEXT
和_DATA
段的WORD 对齐。您已将对齐方式从默认的 WORD 更改为 BYTE,因此出现了您看到的错误。所述TASM 5手册中指出:
段属性非法重新定义
SEGMENT 指令重新打开先前定义的段,并尝试为其赋予不同的属性。例如:
Run Code Online (Sandbox Code Playgroud)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
Run Code Online (Sandbox Code Playgroud)
如果您要组装它,它应该生成一个大小为 25 字节的程序:
Run Code Online (Sandbox Code Playgroud)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
Run Code Online (Sandbox Code Playgroud)
在startupcode
和exitcode
,所以你需要自己生成的代码指令不简化段模型之外工作。由于我假设您正在使用tiny
模型来生成 DOS COM 程序,因此ret
假设您不需要返回错误级别,您可以使用它从 DOS 返回。这减少了程序的大小。不需要设置段寄存器,因为当 DOS 开始运行 COM 程序时,CS=DS=ES=SS 都指向程序段前缀 (PSP)。生成的程序如下所示:
Run Code Online (Sandbox Code Playgroud)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
Run Code Online (Sandbox Code Playgroud)
生成的文件大小为 25 字节,更重要的_DATA
是该段未在 WORD 边界上对齐:
Run Code Online (Sandbox Code Playgroud)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