Mail Archives: djgpp/1997/09/26/08:27:23
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 -