用于链接可执行文件的 /3 键后 DOSBOX 崩溃

问题描述

我在 tasm 下有一个用 dosbox 编写的程序(其文本在下面提供)。
是由我自己为抽象 pl 编写的 c 编写的编译器生成的。
我正在尝试以下列方式编译和运行它:

mount c *some path*
c:
tasm PROGRA~1.asm
tlink PROGRA~1.obj 
PROGRA~1.exe

但我收到错误:

relative jump out of range by 000fh bytes

我知道这样做的原因是说明

;
forStart0:
;
jmp forStart0
;

因为这些标签太“远”了

所以我把 .386 放在我的程序的顶部并再次编译它。现在它通过 tasm command 并在 tlink 上失败并出现错误

32-bit record encountered in module use /3 option

所以命令现在是:

mount c *path *
c:
tasm PROGRA~1.asm
tlink /3 PROGRA~1.obj 
PROGRA~1.exe

现在它也通过 tlink 命令并运行产生的 .exe 并且它的输出是单个字母 Tdosbox 崩溃。 如果我还添加了 /m3

mount c *path *
c:
tasm /m3 PROGRA~1.asm
tlink /3 PROGRA~1.obj 
PROGRA~1.exe

使用这个 dosbox.exe 运行并停止执行后输出几行无意义的符号。

所以我的问题是:出了什么问题以及如何解决? 程序:

;.386
DOSSEG
.MODEL SMALL
.STACK 100h
.DATA
MY_MUL MACRO X,Y,Z
    mov z,0
    mov z+2,0
    mov ax,x
    mul y
    mov z,ax
    mov z+2,dx
    mov ax,x+2
    mul y
    add z+2,ax
    mov ax,z
    mov dx,z+2
ENDM

    _idea   dd  00h
    _ideb   dd  00h
    _idec   dd  00h
    lb1 dw  0h
    lb2 dw  0h
    buf_if  dw  0h
buf dd  0
rc  dw  0
;======strData for input() functions======
    erFlag  db  0
    TStr    db  10 dup (0)
    TBin    dw  0,0
    MaxLen  dw  0
    FlagS   db  0
    Mul10   dw  1,0
    my_z    dw  0,0

    In_Str  db  13,10,'<< $'
    erStr1  db  13,'strData not input_variable',13,'$'
    erStr2  db  13,'Incorrectly data ','$'
    erStr3  db  13,'strData is too long ','$'
;======================================

;=======strData for output===================
    MSign   db  '+','$'
    X_Str   db  12 dup (0)
    ten dw  10
    X1  dw  0h
    MX1 db  13,'>> $'
;======================================

.CODE
start:
    mov ax,@data
    mov ds,ax
finit
fstcw rc
or rc,0c00h
fldcw rc
    call input
    fild buf
    fistp _idea
    call input
    fild buf
    fistp _ideb
    call input
    fild buf
    fistp _idec
forStart0:
    fild _idea
    mov word ptr buf,00002h
    fild buf
    fsub
    fistp buf
    fldz 
    fild buf
    call eq_
    call ltNot
    fistp buf
    mov ax,word ptr buf
    cmp ax,0
    jz forFinish0
    mov word ptr buf,000deh
    fild buf
    fistp buf
    call output
    fild _idea
    mov word ptr buf,00001h
    fild buf
    fsub
    fistp _idea
forStart1:
    fild _ideb
    mov word ptr buf,00004h
    fild buf
    fsub
    fistp buf
    fldz 
    fild buf
    call eq_
    call ltNot
    fistp buf
    mov ax,0
    jz forFinish1
    mov word ptr buf,0007bh
    fild buf
    fistp buf
    call output
    fild _ideb
    mov word ptr buf,00001h
    fild buf
    fsub
    fistp _ideb
jmp forStart1
forFinish1:
jmp forStart0
forFinish0:
    mov word ptr buf,00001h
    fild buf
    mov word ptr buf,00001h
    fild buf
    call ltAnd
    call ltAnd
    fistp _idea
    fild _idea
    fistp buf
    call output
    mov word ptr buf,00000h
    fild buf
    call ltAnd
    call ltAnd
    fistp _idea
    fild _idea
    fistp buf
    call output
    mov word ptr buf,00000h
    fild buf
    mov word ptr buf,00001h
    fild buf
    call ltAnd
    call ltAnd
    fistp _idea
    fild _idea
    fistp buf
    call output
;======================================
MOV AH,4Ch
INT 21h

;====Input procedure Input()=============
INPUT PROC

    push ax
    push bx
    push cx
    push dx
    push di
    push si

    lea dx,In_Str
    mov ah,09
    int 21h
    mov di,offset buf
    mov MaxLen,5
    mov cx,MaxLen

    mov si,0

  In_00:
    mov ah,01
    int 21h
    cmp al,0Dh
    je In_1
    cmp al,'-'
    jne In_0
    mov FlagS,1
    jmp In_00

  In_0:
    mov dl,al
    call CHECK_BYTE
    mov TStr[si],dl
    inc si
    loop In_00

  In_1:
    push si
    dec si
    cmp cx,MaxLen
    jne In_2
    lea dx,erStr1
    mov ah,09
    int 21h
    mov erFlag,1
    jmp In_5

  In_2:
    mov bh,0
    mov bl,TStr[si]
    MY_MUL Mul10,bx,my_z
    add TBin,ax
    adc TBin+2,dx
    mov bh,10
    MY_MUL Mul10,my_z
    mov Mul10,ax
    mov Mul10+2,dx
    dec si
    cmp si,0
    jge In_2
    mov ax,TBin
    mov dx,TBin+2
    pop si
    cmp si,MaxLen
    jl In_3
    cmp MaxLen,5
    jl In_2_1
    js In_Err
    cmp dx,7FFFh
    ja In_Err
    jmp In_3

  In_2_1:
    cmp MaxLen,5
    jl In_2_2
    cmp dx,00
    ja In_Err
    cmp ah,7fh
    ja In_Err
    jmp In_3

  In_2_2:
    cmp ax,007Fh
    jbe In_3

  In_Err:
    lea dx,erStr3
    mov ah,1
    jmp In_5

  In_3:
    cmp FlagS,1
    jne In_4
    mov bx,0
    sub bx,bx
    mov bx,0
    sbb bx,dx
    mov dx,bx

  In_4:
    mov [di],ax
    mov [di+2],dx
    mov TBin,0
    mov TBin+2,0
    mov Mul10,1
    mov Mul10+2,0
    mov FlagS,0

  In_5:

    pop si
    pop di
    pop dx
    pop cx
    pop bx
    pop ax

    ret
input ENDP

CHECK_BYTE  PROC
    sub dl,30h
    cmp dl,00
    jl ErS
    cmp dl,0Ah
    jl GO

  ErS:
    lea dx,erStr2
    mov ah,09
    int 21h

  GO:
    ret
CHECK_BYTE ENDP
;======================================


;===Output procedure output()=============

output PROC

    push ax
    push bx
    push cx
    push dx
    push di
    push si

    mov cl,byte ptr buf+3
    and cl,80h
    je m6
    fild buf
    fchs
    fistp buf
    mov MSign,'-'

  M6:
    mov cx,5
    mov di,0

  O_1:
    ffree st(0)
    ffree st(1)
    fild ten
    fild buf
    fprem
    fistp X1
    mov dl,byte ptr X1
    add dl,30h
    mov X_Str[di],dl
    inc di
    fild buf
    fxch st(1)
    fdiv
    frndint
    fistp buf
    loop O_1

    mov dx,offset MX1
    mov ah,09
    int 21h
    mov dl,MSign
    mov ah,02
    int 21h
    inc di
    mov cx,7

  O_2:
    mov dl,X_Str[di]
    mov ah,02h
    int 21h
    dec di
    loop O_2

    mov MSign,'+'

    pop si
    pop di
    pop dx
    pop cx
    pop bx
    pop ax

    ret
output ENDP
;======================================


;===Procedure mod_====================

mod_ PROC

    fistp lb1
    fistp lb2
    fild lb1
    fild lb2
    fprem
    ret
mod_ ENDP
;======================================


;===Procedure ltAnd====================

ltAnd PROC

    push ax
    push dx
    pushf
    fistp lb1
    fistp lb2
    mov ax,lb1
    cmp ax,0
    jnz true_and1
    jz false_and

  true_and1:
    mov ax,lb2
    cmp ax,0
    jnz true_and

 false_and:
    fldz
    jmp l_and

  true_and:
    fld1

  l_and:

    popf
    pop dx
    pop ax

    ret
ltAnd ENDP
;======================================


;===Procedure ltOr======================

ltOr PROC

    push ax
    push dx
    pushf
    fistp lb1
    fistp lb2
    mov ax,0
    jnz true_or
    mov ax,0
    jnz true_or
    fldz
    jmp l_or

  true_or:
    fld1

  l_or:

    popf
    pop dx
    pop ax

    ret
ltOr ENDP
;======================================


;===Procedure ltNot====================

ltNot PROC

    push ax
    pushf
    fistp lb1
    mov ax,0
    jne is_true
    fld1
    jmp l_not

  is_true:
    fldz

  l_not:

    popf
    pop ax

    ret
ltNot ENDP
;======================================


;===Procedure eq_======================

eq_ PROC

    push ax
    push dx
    pushf
    fistp lb1
    fistp lb2
    mov ax,lb1
    mov dx,dx
    jne not_eq
    fld1
    jmp l_eq

  not_eq:
    fldz

  l_eq:
    popf
    pop dx
    pop ax

    ret
eq_ ENDP
;======================================


;===Procedure ltGreate======================

ltGreate PROC

    push ax
    push dx
    pushf
    fistp lb1
    fistp lb2
    mov ax,lb2
    cmp dx,ax
    jl lov
    fld1
    jmp l_ge

  lov:
    fldz

  l_ge:
    popf
    pop dx
    pop ax

    ret
ltGreate ENDP
;======================================


;===Procedure ltLess======================

ltLess PROC

    push ax
    push dx
    pushf
    fistp lb1
    fistp lb2
    mov ax,ax
    jge gr

  lo:
    fld1
    jmp l_le

  gr:
    fldz

  l_le:
    popf
    pop dx
    pop ax

    ret
ltLess ENDP
;======================================


;===Procedure ltLessEq======================

ltLessEq PROC

    push ax
    push dx
    pushf
    fistp lb1
    fistp lb2
    mov ax,ax
    jg greq

  loeq:
    fld1
    jmp l_leeq

  greq:
    fldz

  l_leeq:
    popf
    pop dx
    pop ax

    ret
ltLessEq ENDP
;======================================

;======================================

end start
END

编辑: 得出的结论是我错误地命名了问题的原因 - 它不是一个 /3 键,而是一个 .386 指令 如果我使用 /3 编译我的任何程序 - 它会像以前一样工作。但是如果我放置 .386 它会在循环\输入和其他任何东西之前崩溃。

解决方法

我的 tasm 版本发出一个

*警告* 假设段是 32 位

您应该使用 .386 after .MODEL SMALL 来保持段为 16 位,或者明确地发出 16 位段而不是使用简化指令。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...