[comp.os.msdos.programmer] TASM can't subtract ...

mmshah@athena.mit.edu (Milan M Shah) (03/01/91)

Hi!

I am trying to assemble Fontedit.asm, a program published in PC-Magazine
vol 7 no. 15 using Turbo Assembler 1.0 (Yup, its 1.0 alright). In the program,
there's a couple of lines that go:

LOADER 	LABEL	BYTE
LOADER_OFFSET	EQU	100H - LOADER

Simple enough, but TASM complains. It says 'Can't add relative addresses.'
First off, 100H is a constant, and not a relative address. Second, I think
its pretty ridiculous for TASM to give an error and die. Maybe a warning,
but to refuse to assemble? Sheesh, here's a number, here's another, and I
want TASM to subtract one from the other, and TASM can't do that? That's
ridiculous, I sez. So I try:

LOADER_OFFSET	EQU	100H - $
LOADER_OFFSET	EQU	100H - OFFSET LOADER
LOADER_OFFSET	=	100H - [each of three options above]

In all cases, TASM complains. It does so even in QUIRKS and MASM mode.

So, I gave a call to Borland on my dime. The semi moron at the other end
wanted an explanation as to why I wanted to do the above. He kept stumbling
on (you know, the answer will probably be negative (Wow! brilliant)), and I
kept asking "So?". I finally had to hang up after ~25 minutes when I realized
that for the price of the call, I could probably pick up a copy of Microsoft's
assembler off the net!!

In any case, since I have already spent the money on the product and more on
entertaining a clown, can anyone suggest a way out? The only solution I know
of (and it semi-works) is that everywhere I want to use LOADER_OFFSET, I have
to first subtract off OFFSET LOADER and then add in 100H. I have no objection
to doing this, save for the fact that LOADER_OFFSET is used in other Equates. 
It bugs me no end that TASM can't subtract two numbers which are completely
and unambiguously defined, and I paid a cool $259 (for the professional C)
package for this. :-(

Thanks for any help!

Milan
.

valley@uchicago (Doug Dougherty) (03/01/91)

mmshah@athena.mit.edu (Milan M Shah) writes:

>Hi!

>I am trying to assemble Fontedit.asm, a program published in PC-Magazine
>vol 7 no. 15 using Turbo Assembler 1.0 (Yup, its 1.0 alright). In the program,
>there's a couple of lines that go:

>LOADER 	LABEL	BYTE
>LOADER_OFFSET	EQU	100H - LOADER

>It bugs me no end that TASM can't subtract two numbers which are completely
>and unambiguously defined, and I paid a cool $259 (for the professional C)
>package for this. :-(

Well, see, there's this principle that my SO & I refer to as "dP/dQ".
The principle is that the derivative of price with respect to quality is
(almost always) negative.  Often stated as "the more you pay, the less
you get".

Get A86 from Isaacson Software...

ralf+@cs.cmu.edu (Ralf Brown) (03/02/91)

In article <1991Mar1.014835.7651@athena.mit.edu> mmshah@athena.mit.edu (Milan M Shah) writes:
}I am trying to assemble Fontedit.asm, a program published in PC-Magazine
}vol 7 no. 15 using Turbo Assembler 1.0 (Yup, its 1.0 alright). In the program,
}there's a couple of lines that go:
}
}LOADER 	LABEL	BYTE
}LOADER_OFFSET	EQU	100H - LOADER
}
}Simple enough, but TASM complains. It says 'Can't add relative addresses.'
}First off, 100H is a constant, and not a relative address. Second, I think
}its pretty ridiculous for TASM to give an error and die. Maybe a warning,
}but to refuse to assemble? Sheesh, here's a number, here's another, and I
}want TASM to subtract one from the other, and TASM can't do that? That's
}ridiculous, I sez.

It's actually a linker limitation.  LOADER doesn't necessarily end up in the
executable at the same offset as the assembler's location counter indicates.
You *can* say "EQU LOADER-100h", because the assembler can put a -100h in
the location and tell the linker to adjust it by the offset of LOADER.
Unfortunately, the assembler can't tell the linker to fixup a location
by the negative of an address....  The assembler used by FONTEDIT's author
probably has a bug that lets it do the arithmetic and store the value as
a constant in the .OBJ.  Unfortunately, you will get rather hard to find
errors on multi-file programs (I know, I once got bitten by such a problem 
with MASM 2.04) because the final executable will address the wrong
location.

BTW, TASM 2.0 has a more informative message: "Can't subtract dissimilar
relative quanties".  (If they were the same, i.e. LOADER1-LOADER2, where
both are in the same segment, the result would be a constant and would
be independent of any relocation performed by the linker)



--
{backbone}!cs.cmu.edu!ralf  ARPA: RALF@CS.CMU.EDU   FIDO: Ralf Brown 1:129/3.1
BITnet: RALF%CS.CMU.EDU@CMUCCVMA   AT&Tnet: (412)268-3053 (school)   FAX: ask
DISCLAIMER?  Did  | It isn't what we don't know that gives us trouble, it's
I claim something?| what we know that ain't so.  --Will Rogers

abcscnuk@csunb.csun.edu (Naoto Kimura (ACM)) (03/08/91)

In article <1991Mar1.014835.7651@athena.mit.edu> mmshah@athena.mit.edu (Milan M Shah) writes:
]Hi!
]
]I am trying to assemble Fontedit.asm, a program published in PC-Magazine
]vol 7 no. 15 using Turbo Assembler 1.0 (Yup, its 1.0 alright). In the program,
]there's a couple of lines that go:
]
]LOADER 	LABEL	BYTE
]LOADER_OFFSET	EQU	100H - LOADER
			  ^      ^
			  |      `--- An address
			  `---------- A constant

    I think your problem is that you're confusing the assembler with trying to
    subtract an address from a constant.

] .... (text deleted) ...
]
]Thanks for any help!
]
]Milan
].

I would suggest having something like the following:

			ORG	100H	; if you've got a COM file.
	Beginning	LABEL	BYTE
	...
	Loader	LABEL	BYTE
	Loader_offset	EQU	Beginning-Loader
	...

You could alternatively try something like:

	CODE	SEGMENT	BYTE	'CODE'
		; Dang! I can't recall the full syntax for the SEGMENT
		; directive, since mostly use the simplified CODESEG
		; DATASEG, and STACKSEG directives anyway.
	...
	Loader	LABEL	BYTE
	Loader_offset	EQU	CODE:100H-Loader
	...
	ENDS


                //-n-\\			 Naoto Kimura
        _____---=======---_____		 (abcscnuk@csuna.csun.edu)
    ====____\   /.. ..\   /____====
  //         ---\__O__/---         \\	Enterprise... Surrender or we'll
  \_\                             /_/	send back your *&^$% tribbles !!