delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1997/09/26/08:27:23

Date: Fri, 26 Sep 1997 04:48:59 +0000 ( )
From: "Gurunandan R. Bhat" <grbhat AT unigoa DOT ernet DOT in>
To: DJ Delorie <dj AT delorie DOT com>
Cc: djgpp AT delorie DOT com
Subject: Re: Segments vs Selectors
In-Reply-To: <199709260124.VAA08172@delorie.com>
Message-Id: <Pine.LNX.3.91.970926044706.578A-100000@aditya.unigoa.ernet.in>
Mime-Version: 1.0

In continuation of this very illuminating thread on memory 
layout in protected mode, I would like to post a small 
and simple program whose output I cannot explain for some
time now.

The program defines a char, say x, obtains its address and
its distance from the top of the segment. It then dereferences
a pointer pointing a fixed distance (requested from the user) 
above x. I expect the dpmi host (cwsdpmi, in my case) to trash
my program as soon as I dereference a byte above segment limit
(obtained from ___dpmi_get_segment_limit(...)). But this does 
not happen! It is only when I dereference 64K *above* the stated
segment limit that my program trashes. What is happening here?
I hope (pray?) that I am not doing something as silly as a 
goof in my hex arithmetic!! 

Moreover, while the segment_limit is stated as 0x5ffff, the 
Call frame traceback after my program deservedly crashes 
believes it to be 0x6ffff. Why this 64K mercy buffer?

The following code was compiled with:

gcc version 2.7.2.1
CWSDPMI V0.90+ (r3)

gcc -Wall -O2 -m486 gpftest.c -o gpftest.exe

---------------file:gpftest.c-------------------------------
#include<stdio.h>
#include<dpmi.h>
#include<sys/segments.h>

int main(void)
{
   char x;
   unsigned long seg_lim, max_addr;
   unsigned long x_addr, raise_addr, seek_addr;

   x = 0;
   x_addr = (unsigned long) &x;
   seg_lim = __dpmi_get_segment_limit(_my_ds());

   max_addr = seg_lim - x_addr;

   printf("%lx bytes above x, upto %lx in this segment\n",  max_addr, seg_lim);
   printf("Enter the amount by which you want to raise x: ");
   scanf("%lx", &raise_addr);

   seek_addr = x_addr + raise_addr;

   printf("The value at %lx is %d\n", seek_addr, (char) *((char *) seek_addr));

   return(1);
}

   

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019