[comp.sys.ibm.pc] Please explain this MASM/LINK behavior...

lotto@wjh12.UUCP (08/31/87)

I was writing a tiny utility the other day and I ran into this behavior.
The following example is not supposed to DO anything but illustrate the
problem...

Code_Seg	Segment Para 'CODE'

	Assume	CS:Code_Seg
	Org	100H

Begin:	mov	ax, Code_Seg:[2ch]

Code_Seg	Ends
	End	Begin


assembles fine, but generates a link error (invalid object module).
On further investigation, MASM appears to be generating a FIXUP
record with a target THREAD field that uses a METHOD 4. Now the
Microsoft version of the Intel object module docs clearly :-)
states that for target threads, method equals from 0 to 7 MOD 4
which leaves 4 out in the cold.  If you rewrite the Begin line
to read:

Begin:	mov	ax, [2ch]

everything works OK.  I repeat that MASM generates NO warnings
or errors of any kind.

In light of the recent posting by Microsoft documenting the linker
behavior in such fine detail, perhaps someone from the assembler
division would be kind enough to take a stab at this one?
-- 
Gerald Lotto - Harvard Chemistry Dept.
UUCP:  {seismo,harpo,ihnp4,linus,allegra,ut-sally}!harvard!lotto
ARPA:  lotto@harvard.harvard.edu

perkins@bnrmtv.UUCP (09/01/87)

In article <88@wjh12.HARVARD.EDU>, lotto@wjh12.HARVARD.EDU (Jerry Lotto) writes:
> Code_Seg	Segment Para 'CODE'

> 	Assume	CS:Code_Seg
> 	Org	100H

> Begin:	mov	ax, Code_Seg:[2ch]

> Code_Seg	Ends
> 	End	Begin

> assembles fine, but generates a link error (invalid object module).

> If you rewrite the Begin line
> to read:

> Begin:	mov	ax, [2ch]

> everything works OK.  I repeat that MASM generates NO warnings
> or errors of any kind.

The problem is with MASM not complaining about the

	mov     ax, Code_Seg:[2ch]

line.  This SHOULD be written as

	mov     ax, cs:[2ch]

if you want to make use of the ASSUME directive and specify the
code segment.  There's no 8086 addressing mode that allows a
segment to be specified as immediate data for a MOV instruction.
Of course, since you're making a .COM file, you can make use of
the fact that CS and DS both already point to your one and only
segment, and omit the segment override, which then defaults to
using DS.  That's what you're doing in the example that works.
If you had any data declarations in this segment, you'd also
want to put in an

	Assume  DS:Code_Seg

In the several iterations of MASM, Microsoft has managed to make
it fairly reliable in assembling correct instructions, but they're
still woefully lacking in error handling capability.
-- 
{hplabs,amdahl,ames}!bnrmtv!perkins         --Henry Perkins

It is better never to have been born.  But who among us has such luck?
One in a million, perhaps.

lotto@wjh12.HARVARD.EDU (Jerry Lotto) (09/02/87)

In article <2474@bnrmtv.UUCP> perkins@bnrmtv.UUCP (Henry Perkins) writes:
>
>The problem is with MASM not complaining about the
>
>	mov     ax, Code_Seg:[2ch]
>
>line.  This SHOULD be written as
>
>	mov     ax, cs:[2ch]
>
>if you want to make use of the ASSUME directive and specify the
>code segment.  There's no 8086 addressing mode that allows a
>segment to be specified as immediate data for a MOV instruction.

Whoa! Segment overrides to operand fetches are NOT a function of the
instruction.  These two cases above should generate the same code!
The CS assume should work two ways. MASM "knows" that Code_Seg is in
CS: and should not have to be told twice.

You are absolutely correct that using CS: explicity works. The point
was that using CS: implicitly fails (but should not).

You also correctly pointed out that my posted workaround ends up using
DS: (the default). I should have specified your line above as the
workaround example in my original posting to illustrate the problem more
clearly.

BTW, Microsoft tech support acknowledged this as a known bug after my
posting and are supposed to be getting back to me with a real work
around that permits me to use a segname. Explicit use of CS: because
there is other code that has to look at stuff in Code_Seg from the
outside. They claim that MASM 5.0 does not share this problem.
-- 
Gerald Lotto - Harvard Chemistry Dept.
UUCP:  {seismo,harpo,ihnp4,linus,allegra,ut-sally}!harvard!lotto
ARPA:  lotto@harvard.harvard.edu

greg@gryphon.CTS.COM (Greg Laskin) (09/04/87)

In article <2474@bnrmtv.UUCP> perkins@bnrmtv.UUCP (Henry Perkins) writes:
>In article <88@wjh12.HARVARD.EDU>, lotto@wjh12.HARVARD.EDU (Jerry Lotto) writes:
>> Code_Seg	Segment Para 'CODE'
>
>> 	Assume	CS:Code_Seg
>> 	Org	100H
>
>> Begin:	mov	ax, Code_Seg:[2ch]
>
>> Code_Seg	Ends
>> 	End	Begin
>
>> assembles fine, but generates a link error (invalid object module).
>The problem is with MASM not complaining about the
>
>	mov     ax, Code_Seg:[2ch]
>
>line.  This SHOULD be written as
>
>	mov     ax, cs:[2ch]
>
>if you want to make use of the ASSUME directive and specify the
>code segment.  There's no 8086 addressing mode that allows a
>segment to be specified as immediate data for a MOV instruction.

The assembler documentation asserts that the assembler will
resolve Code_Seg:[2ch] to CS:[2ch]. (see below)

>Of course, since you're making a .COM file, you can make use of
>the fact that CS and DS both already point to your one and only
>segment, and omit the segment override, which then defaults to
>using DS.  That's what you're doing in the example that works.

Accurate.

>If you had any data declarations in this segment, you'd also
>want to put in an
>
>	Assume  DS:Code_Seg
>
provided that you had assured that DS would contain the value of
Code_Seg at run-time.  The Assume directive is a cue to the assembler
about what segment addresses will be in the segment registers at
run-time.  This directive is a "guarantee" to the assembler.  If
DS is not actually pointing at Code_Seg, the assembler will (and
can not) do anything about it.

Ther MASM 4.0 reference manual says, in section 5.3.7, Segment-Override
Operator:

SYNTAX
segmentregister:expression
segmentname:expression
groupname:expression

... if either sementname or groupname is given, the name must have been
assigned to a segment register with a previous ASSUME directive and
defined using a SEGMENT or GROUP directive.  The expression can be an
absolute symbol or relocatable operand.  The segmentregister must be CS,
DS, SS or ES.

---- end of quotation ---

Code_Seg is a segmentname and a relocatable operand.  CS is a segmentregister
and is an absolute operand.

It would seem that one could reasonably expect to generate the code for
the sample correctly.  In fact, the code in the assembly listing IS
correct.  Once the assembler had resolved the relocatable Code_Seg to
the absolute CS, it should have stopped (while it was ahead). 

It doesn't seem unfair to expect the assembler to correctly generate
the sample code.

That said, it doesn't work.  Specify CS explicitly as a work-around.
-- 
Greg Laskin   
"When everybody's talking and nobody's listening, how can we decide?"
INTERNET:     greg@gryphon.CTS.COM
UUCP:         {hplabs!hp-sdd, sdcsvax, ihnp4}!crash!gryphon!greg
UUCP:         {philabs, scgvaxd}!cadovax!gryphon!greg