问题描述
我在 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
并且它的输出是单个字母 T
和 dosBox
崩溃。
如果我还添加了 /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 位段而不是使用简化指令。