delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/2008/10/05/21:00:07

X-Authentication-Warning: delorie.com: mail set sender to djgpp-bounces using -f
From: "Rod Pemberton" <do_not_have AT nohavenot DOT cmm>
Newsgroups: comp.os.msdos.djgpp
Subject: failure of __dpmi_set_segment_limit() problem
Date: Sun, 5 Oct 2008 20:52:41 -0400
Organization: Aioe.org NNTP Server
Lines: 125
Message-ID: <gcbnih$6pq$1@aioe.org>
NNTP-Posting-Host: mQokHQeKeRC37oD/Mq9UYg.user.aioe.org
Mime-Version: 1.0
X-Complaints-To: abuse AT aioe DOT org
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2800.1933
X-Newsreader: Microsoft Outlook Express 6.00.2800.1933
X-Priority: 3
X-MSMail-Priority: Normal
To: djgpp AT delorie DOT com
DJ-Gateway: from newsgroup comp.os.msdos.djgpp
Reply-To: djgpp AT delorie DOT com

I added some *inactive* code to a routine in a program I was working on when
it began faulting in main().  I traced the problem to
__dpmi_set_segment_limit() from the fault info.  The limit hadn't been
changed.  __dpmi_set_segment_limit wasn't returning an error code either.
The problem appears as __dpmi_set_segment_limit() working at first, but then
the selector limit is being reset to its pre-call value.  I.e., two
back-to-back calls to __dpmi_get_segment_limit return two different values,
sometimes.  The following C code represents the issue, but won't run as is
since it doesn't align main() properly.  The assembly code below has been
adjusted (.space 0x7167) for the missing code and will need to be compiled
as "gcc -o test.exe test.s".  I've tested this under RM MS-DOS v7.10 w/DJGPP
v2.03 (GCC 3.4.1), DJGPP v2.04 (GCC 4.1.0), CWSDPMI v5 old and new, CWSDPMI
three 6b versions, PMODETSR, etc.  All combinations I've tried fail.  I'm
not sure why this only happens under these circumstances.  Am I doing
something wrong?  Any help?

---C---
#include <stdio.h>
#include <go32.h>
#include <dpmi.h>

unsigned int misc[60];
unsigned int stack[4096];

#if 0
/* bunch of removed code which aligns main() to offset 0x7617 */
#endif

/* first call to get limit prints: ffffffff */
/* second call to get limit should print: ffffffff */
/* second call usually prints ffffffff */
/* but, second call prints 0000afff when main() is at offset 0x7617 */

int main(void)
{
  unsigned long i;
  unsigned char k[256]="ABCD";

  __dpmi_set_segment_limit(_my_ds(),0xFFFFFFFF);
printf("%08lx\n",__dpmi_get_segment_limit(_my_ds()));
printf("%08lx\n",__dpmi_get_segment_limit(_my_ds()));

  return(0);
}

---assembly---
 .file "test.c"
 .section .text
.space 0x7617
LC1:
 .ascii "%08lx\12\0"
LC0:
 .ascii "ABCD\0"
 .space 251
.globl _main
_main:
 leal 4(%esp), %ecx
 andl $-16, %esp
 pushl -4(%ecx)
 pushl %ebp
 movl %esp, %ebp
 pushl %ecx
 subl $276, %esp
 movl LC0, %eax
 movl %eax, -264(%ebp)
 movb LC0+4, %al
 movb %al, -260(%ebp)
 leal -259(%ebp), %edx
 movl $251, %eax
 subl $4, %esp
 pushl %eax
 pushl $0
 pushl %edx
 call _memset
 addl $16, %esp
 call __my_ds
 subl $8, %esp
 pushl $-1
 pushl %eax
 call ___dpmi_set_segment_limit
 addl $16, %esp
 call __my_ds
 subl $12, %esp
 pushl %eax
 call ___dpmi_get_segment_limit
 addl $16, %esp
 subl $8, %esp
 pushl %eax
 pushl $LC1
 call _printf
 addl $16, %esp
 call __my_ds
 subl $12, %esp
 pushl %eax
 call ___dpmi_get_segment_limit
 addl $16, %esp
 subl $8, %esp
 pushl %eax
 pushl $LC1
 call _printf
 addl $16, %esp
 movl $0, %eax
 movl -4(%ebp), %ecx
 leave
 leal -4(%ecx), %esp
 ret
__my_ds:
 pushl %ebp
 movl %esp, %ebp
 subl $16, %esp
/APP
 movw %ds,%ax
/NO_APP
 movw %ax, -2(%ebp)
 movw -2(%ebp), %ax
 andl $65535, %eax
 leave
 ret
.comm _misc,240
.comm _stack,16384


Rod Pemberton

- Raw text -


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