When is DGROUP/@data required to set up ds?

Started by allynm, May 02, 2011, 10:34:21 PM

Previous topic - Next topic

allynm

Hi Steve,

Thanks for the reference.  I'll see if I can get a copy.  My asm library is pretty meager--mostly Randy Hyde + MASM 6.1 Programmer's Guide. 

I did a little further investigation into my segment questions.  I added a couple of lilnes to the code that MichaelW used.  Namely, I loaded ES with the address of my DSEG problem child.  _DATA loads DS at 0C58 and DSEG loads at ES=0C85, 37 paragraphs away.  16 bytes per para X 37 paragraphs = 880 bytes away.  The "howdy" string actually begins at offset 1 from 0C85, or in other words, 881 bytes away from offset 0 of _DATA.  We know from the .map that Michael produced that the length of the _DATA seg is in fact 371h or 881d.  So it makes sense arithmetically. 

What I don't "get" is why I can't go directly to DSEG when I load ds.  All the offsets got to be recalculated by the llinker when it plops this stuff inside of DGROUP  --which seems like a waste of effort.  Somehow it seems to me that there should be a way to override the .model directive so it doesn't just take it upon itself to force my DSEG into DGROUP.

I read some language in Hyde's chapter on segments, right at the end where he attempts to explain the algo that MASM goes thru to address segments that are plopped into DGROUP.  Very confusing..  Somehow it seems like there should be a syntax of the form DGROUP:DSEG that would permit one to go directly to DSEG rather than referencing DGROUP AKA _DATA.  On the other hand, that is sort of silly since it just means more typing...but, I submit that it is conceptually much clearer and might have other benefits.

Thanks again
Mark

MichaelW

Quote from: allynm on May 03, 2011, 07:05:28 PM
One point I don't understand has to do with the _DATA segment (as named in the .map file).  In my code the _DATA segment is 371h bytes.  What's inside this segment?

Most of the segment contents are related to the Borland library. The attachment contains a modified version of your source that uses my support module to display the contents of the segment. The map file shows a length of 74Bh, and it clearly includes the data for the support module.
eschew obfuscation

allynm

Good morning, MichaelW.

Thanks for your further investigation and assistance.  Later this morning I will run the code. 

Regards,
Mark

FORTRANS

Quote from: allynm on May 03, 2011, 08:10:28 PM
What I don't "get" is why I can't go directly to DSEG when I load ds.  All the offsets got to be recalculated by the llinker when it plops this stuff inside of DGROUP  --which seems like a waste of effort.  Somehow it seems to me that there should be a way to override the .model directive so it doesn't just take it upon itself to force my DSEG into DGROUP.

Hi,

   That seems to be for the HLL compatibility.  Checking an _old_
ASM reference, showed an example of using the GROUP directive to
create DGROUP to interface with High Level Languages (HLL).  You
could declare another segment and use it directly, but passing
references to a C routine would presumably then be fubared.  You
could try reordering the segments in DGROUP using GROUP so that
DSEG was first, but that seems that it might also have side effects.

   HLL compatibility was only used a few times by me, and I just did
some simple things that ASM did easily, and FORTRAN, well... I didn't
quite do the fight to the death with the documentation to see how/if
they could be done.

Regards,

Steve N.

allynm

Hi Steve N.

Your conjecture about why DGROUP is important for HLL interfacing seems borne out by what MichaelW. found when he inspected the inside of _DATA and found a lot of Borland C stuff inside it.  It would seem therefore likely that creating a new GROUP with DSEG as first member would likely have the kind of side effects you mention.

BTW, I ordered the book from Amazon used book dealer for 18 bucks.  The book must have been very popular in its field because it was available from a lot of used book vendors.

Thanks,
Mark

FORTRANS

Quote from: allynm on May 04, 2011, 04:42:15 PM
BTW, I ordered the book from Amazon used book dealer for 18 bucks.  The book must have been very popular in its field because it was available from a lot of used book vendors.

Hi Mark,

   Can't comment on its popularity, and I hope you like it.  It's
a bit odd compared to other assembly books I have, maybe
because it is a textbook.  I tend to use it as a friendly MASM
reference.  He apparently wanted to be understood, whereas
the M$ documentation wants to be terse and accurate (maybe).

Cheers,

Steve N.

allynm

Hello MichaelW,

Thanks so much for including the support.asm file. It has many very useful macros and looks to me as if it is something you've built over many years.  It was very generous of you to share it. 

I see what you did with my little pgm and it was very helpful explanation.

Regards,
Mark Allyn

allynm

Hello MichaelW,

One last question, if I may.  I redid my little program to incorporate your support.asm code.  The result was successful.  But, I have just one uncertainty about how to interpret the seg:offset pairs that are printed out when the program runs. These pairs are not written the "same" as their counterpart pairs that show up in codeview when I dump memory during a codeview session on the same program.

Is it correct to assume that they are different because the codeview seg:offset pairs are NOT physical addresses, but the pairs showing up during the execution of the program ARE physical addresses?  Or is something else happening?

Thanks,

Mark

dedndave

keep in mind that, when codeview or a debugger are running, they are loaded first
so, the addresses reported are likely to be higher by the amount of space the debugger consumes

MichaelW

Hi Mark,

If I load the program into CV, execute the first two instructions so DS is set to the data segment instead of to the PSP, then start with a "d ds:0" and proceed through the memory, the segment and offset addresses and the data at those addresses match what I see when I run the program within CV. When I run the program on its own, everything except the segment addresses match the dump in CV. The difference in the segment addresses is due to a difference in the load addresses. The segment/offset pairs that you see represent physical addresses. Under RM DOS the represented addresses would match the physical addresses, but under Windows, who knows what's actually where. It's been so long since I used CV that I don't recall what a typical load address would be.

eschew obfuscation

allynm

Hi 'Dave and MichaelW,

Yes, I observed exactly what MichaelW observes. 

I noted the segment addresses for the CV session and the segment addresses as reported when the program uses MichaelW's memdump macro. 

When the CV session runs on my little proggy, my program DS segment address is 0CBA.  When the program dumps memory for the DS register, the segment address is 0791.  My version of CV reports that the .exe consumes 490,768 bytes of storage.  My segment arithmetic isn't at all trustworthy, but I think that the difference between 0CBA0 and 07910 is not as great as 490,768.  This was my crude attempt to test 'Dave's suggestion.  Maybe I did it wrong?  After all, as we used to say, the difference is "in the right direction"...

Regards,
Mark

allynm

Hello 'Dave and MichaelW and others following this thread,

I made a final modifcation to the DGROUP program to print the value of one of the variables.  This led to an interesting discovery.  Namely, the ds: segment override operator is required in order for the program to assemble.  Without it, the assembler generates an error.  What is also interesting is that the printf C function does NOT have any problem getting the string "strng" or the format string. 

I don't understand why the segment override is required. If the dseg segment loads second behind _DATA and the loader can find the strng in the dseg segment in order to execute printf why can't it find eks?

Here's the code:


.model large, c
.386

include c:\masm32\mymasm\michaelw\support.asm

printf PROTO C, :VARARG

sseg segment byte stack 'stack'
db 256 dup ('stack   ')
sseg ends
dseg segment byte public 'data'

strng db "howdy$", 13, 10, 0
fmt1 db "%s", 0
fmt2 db "the value of w in memory is %d ", 13, 10, 0

eks word 64
dseg ends


cseg segment byte public 'code'

main PROC

mov ax, _data ;DGROUP
mov ds, ax

invoke printf, aDDR fmt1, ADDR strng  ;NOTE - ds override is NOT required

mov ax, ds:eks ;NOTE-  ds segment override is required

invoke printf, ADDR fmt2, ax
mov dx, OFFSET ds:strng ;NOTE-  ds segment override is required
mov ah, 09h
int 21h
exit:
mov ah, 4Ch
int 21h
main ENDP
cseg ends

end main


Regards,
Mark

dedndave

that's because you have no ASSUME DS:dseg

dedndave

i am curious to see if this will assemble and run

the following are listed in the make.bat file - you must provide them

c0l.obj
fp87.lib
emu.lib
mathl.lib
cl.lib

not sure what c0l.obj is   :P
you may be able to remove it

if you send me all the files listed above, i can experiment with them  :U

allynm

Hi Dedndave-

Yes, that's what I thought too.  I had previously tried your idea. I added ASSUME ds:dseg before I posted this and in fact the program will assemble and will produce a .exe file but it terminates abnormally when it hits the printf statement.  The only way I could get it to run successfully was with the segment override. 

I haven't tried to do what you propose in the second response.  I looked at C0L.obj briefly using notepad.  It looks like cl.lib inasmuch as the same C functions are identified in it as show up in cl.lib.  I suppose you know that the l in c0l and cl refers to large model.

Thanks for taking yet another look at this problem.

Mark