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