I have a program written in tasm
under dosbox
(its text is provided below).
Is is produced by my own c-written compiler for abstract pl.
I am trying to compile and run it in the following way:
mount c *some path*
c:
tasm PROGRA~1.asm
tlink PROGRA~1.obj
PROGRA~1.exe
but i am getting and error:
relative jump out of range by 000fh bytes
I know the reason for this is the instructions
;
forStart0:
;
jmp forStart0
;
because these labels are too "far away"
so i put .386
at the top of my program and compile it again. Now it passes tasm command
and fails on tlink
with error
32-bit record encountered in module use /3 option
so command now is:
mount c *path *
c:
tasm PROGRA~1.asm
tlink /3 PROGRA~1.obj
PROGRA~1.exe
Now it passes also tlink
commad and runs produced .exe
and its output is single letter T
and dosbox
crashes.
If i also add /m3
:
mount c *path *
c:
tasm /m3 PROGRA~1.asm
tlink /3 PROGRA~1.obj
PROGRA~1.exe
With this dosbox
output few rows of meaningless symbols after .exe
run and stops execution.
So my question is: what is wrong and how to fix it? program:
;.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,10,'strData not input_variable',13,10,'$'
erStr2 db 13,10,'Incorrectly data ',13,10,'$'
erStr3 db 13,10,'strData is too long ',13,10,'$'
;======================================
;=======strData for output===================
MSign db '+','$'
X_Str db 12 dup (0)
ten dw 10
X1 dw 0h
MX1 db 13,10,'>> $'
;======================================
.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,word ptr buf
cmp 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
mov word ptr buf,00001h
fild buf
call ltAnd
call ltAnd
fistp _idea
fild _idea
fistp buf
call output
mov word ptr buf,00001h
fild buf
mov word ptr buf,00001h
fild buf
mov word ptr buf,00000h
fild buf
call ltAnd
call ltAnd
fistp _idea
fild _idea
fistp buf
call output
mov word ptr buf,00001h
fild buf
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 word ptr buf,00001h
fild buf
mov word ptr buf,00000h
fild buf
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
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
mov word ptr buf,00001h
fild buf
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,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,0
mov bl,10
MY_MUL Mul10,bx,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,09
int 21h
mov erFlag,1
jmp In_5
In_3:
cmp FlagS,1
jne In_4
mov bx,0
sub bx,ax
mov ax,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,lb1
cmp ax,0
jnz true_or
mov ax,lb2
cmp 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,lb1
cmp 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,lb2
cmp ax,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,lb1
mov dx,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, lb1
mov dx, lb2
cmp dx,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, lb1
mov dx, lb2
cmp dx,ax
jg greq
loeq:
fld1
jmp l_leeq
greq:
fldz
l_leeq:
popf
pop dx
pop ax
ret
ltLessEq ENDP
;======================================
;======================================
end start
END
EDIT:
came to the conclusion that I incorrectly named the cause of the problem - it was not a /3
key, but a .386
directive
If i compile my any program using /3
- it works as earlier. But if i place .386
it crashes before loops\input and anything else.
My version of tasm emits a
*Warning* Assuming segment is 32 bit
You should use the .386
after the .MODEL SMALL
to keep segments 16 bit, or explicitly emit 16 bit segments instead of using the simplified directives.