TIP: Click on subject to list as thread! ANSI
echo: os2prog
to: Russ Parks
from: Mike Bilow
date: 1996-01-28 02:03:50
subject: CSet++ and Asm

Russ Parks wrote in a message to All:

 RP>   The problem is accessing storage from ASM. The FSTCW
 RP> requires writing a 16-bit word, but every time I try it, I
 RP> get an access violation/page fault. The problem isn't in the
 RP> function declaration or anything like that, because a simple
 RP> FLD1 returns 1.0...just as it should, without any exceptions
 RP> raised. 

This is a good idea for a test, since the only difference is whether you
touch memory or not.  Your problem is in the linker, since you got an ASM
pseudo-op out of order.  I'll explain below.

 RP>   Here's the .ASM file (I'm using MASM 5.1)

 RP>         .386
 RP>         .387

 RP> CODE32  SEGMENT PARA USE32 PUBLIC 'CODE'
 RP> CODE32  ENDS

 RP> DATA32  SEGMENT PARA USE32 PUBLIC 'DATA'

You need an ASSUME DS such that it matches whatever you ASSUME DS in CODE32.

 RP>         TempCw  DW  0                   ;Temp storage for
 RP> use with the         OldCw   DW  0                   ;80x87
 RP> control word
 RP> DATA32  ENDS

 RP>         ASSUME CS:CODE32, DS:DATA32

Your ASSUME directives need to be *within* the segments.

 RP> CODE32  SEGMENT

Move the ASSUME to here, after SEGMENT.

 RP>         PUBLIC  FPOWER__FrT1    ;A mangled name, of course :-)
 RP> FPOWER__FrT1    PROC

 RP>         fstcw   OldCw   ;This causes SYS3175 (acc. violation
 RP> or page fault) 

FSTCW is being executed with DS dangling and the offset meaningless.  You
could have done an explicit register override here with the operand set to
DATA32:[OldCW], but that is not the right approach.

 RP>         fld1            ;A harmless instruction. It works
 RP> right, too :) 

This works because it does not depend upon the linker relocation of DS.

 RP>         ret
 RP> FPOWER__FrT1    ENDP
 RP> CODE32  ENDS
 RP> END

You are being blown away by the linker, which is causing the segment
grouping to compute funny addresses.  Since you are linking with C
generated code, the linker has to realize that the offset within your local
segment (DATA32) is different from that with the group of all segments
sharing the combine class ('DATA').  This is why you need GROUP and ASSUME
directives, since you cannot accept the assembler default.

Another really annoying thing about this is that the assembler output
listing is exactly identical whether you do this correctly or not, since
the addresses are all marked relocatable ('R') in any case.  You could have
found this by studying the linker map file, if you really know what you are
doing, or with a debugger and a breakpoint on the FSTCW instruction.

You may think this is stupid in connection with 32-bit flat-mode code where no 
one ever changes DS, and you would be right, except that the people writing 
MASM 5.1 did not know that at the time.  Had you used the ".MODEL
NEAR", ".DATA", and ".CODE" directives in
combination with the ".386p" directive, I think this might have
worked.
 
-- Mike


--- 
* Origin: N1BEE BBS +1 401 944 8498 V.34/V.FC/V.32bis/HST16.8 (1:323/107)
SEEN-BY: 50/99 270/101 620/243 711/401 409 410 413 430 808 809 934 955
SEEN-BY: 712/407 515 517 628 713/888 800/1 7877/2809
@PATH: 323/107 170/400 396/1 270/101 712/515 711/808 809 934

SOURCE: echomail via fidonet.ozzmosis.com

Email questions or comments to sysop@ipingthereforeiam.com
All parts of this website painstakingly hand-crafted in the U.S.A.!
IPTIA BBS/MUD/Terminal/Game Server List, © 2025 IPTIA Consulting™.