【问题标题】:set the alignment of the data segment in TASM ideal mode在 TASM 理想模式下设置数据段的对齐方式
【发布时间】:2020-11-26 03:44:47
【问题描述】:

我的汇编源代码:

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 

TASM 5.0 给出了错误段属性非法重新定义,其中包含byte 的行。

如何在理想模式下将数据段改为字节对齐?

我需要它,因为我不想在生成的 .com 文件中的 lpText 前面有一个额外的 0 字节。我希望 .com 文件尽可能小。

【问题讨论】:

    标签: assembly x86 dos x86-16 tasm


    【解决方案1】:

    如果您打算重新打开像_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
    

    startupcodeexitcode 指令在简化段模型之外不起作用,因此您需要自己生成代码。由于我假设您正在使用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
    

    【讨论】:

    • 感谢您提供这些选项的所有详细信息。我的 TL;DR 是在 TASM 中使用 model 时,无法更改段对齐方式。
    猜你喜欢
    • 1970-01-01
    • 2013-04-18
    • 2012-04-28
    • 2013-10-06
    • 2014-08-12
    • 1970-01-01
    • 2017-08-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多