delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1998/05/08/03:15:24

From: "Rob van Berkel" <rvberkel AT EuroNet DOT NL>
Newsgroups: comp.os.msdos.djgpp
Subject: HELP : call to inter-segment code (lcall)
Date: 8 May 1998 07:00:32 GMT
Organization: EuroNet Internet
Lines: 57
Message-ID: <6iuaig$qh4@news.euro.net>
NNTP-Posting-Host: i135.ztm.euronet.nl
To: djgpp AT delorie DOT com
DJ-Gateway: from newsgroup comp.os.msdos.djgpp

Hi
Im trying to do a long call with inline assembly to a linear address that
does not reside in my current CS-selector. More specifically, I'm trying to
call the BIOS32 entrypoint. I set up the right LDT selector for my code but
as soon as i reach the lcall instruction i bail out with a SIGSEGV. I think
I'm not allowed to call that address or what?. Any idea what is going wrong?

Here are some code-snippets:

===== start of code

static __dpmi_paddr bios32_indirect = {0L, 0};   // this struct holds the
pmode address we're gonna call: (offset,selector)
__dpmi_meminfo mi;   // struct to set base and limit of selector

<<cut>>

bios32_indirect.offset32 = pcibios_init();   // gets the 32bit linear
address of the entry point.

memset(&mi,0,sizeof(mi));
mi.address = bios32_indirect.offset32 & 0xfffff000L;   // lower page boudary
mi.size = 0x2000;   // 2 pages of 4k

// set up the code-selector
bios32_cs_sel = __dpmi_create_alias_descriptor(_my_cs())   // might as well
just create a clean one - no difference
__dpmi_set_segment_base_address(bios32_cs_sel, mi.address)
__dpmi_set_segment_limit(bios32_cs_sel, mi.size - 1)
__dpmi_set_descriptor_access_rights(bios32_cs_sel,0x40fa)  // setup for 1bit
granularity, non-system, readable code segment
        bios32_indirect.selector = bios32_cs_sel;

// with this setup I try to call the following routine:

static unsigned long bios32_service(unsigned long service)
{
        unsigned char return_code;      /* %al */
        unsigned long address;          /* %ebx */
        unsigned long length;           /* %ecx */
        unsigned long entry;            /* %edx */
        unsigned long flags;

        save_flags(flags);
        __asm__("lcall (%%edi)"
                : "=a" (return_code),
                  "=b" (address),
                  "=c" (length),
                  "=d" (entry)
                : "0" (service),
                  "1" (0),
                  "D" (&bios32_indirect));
        restore_flags(flags);

======= end of code


- Raw text -


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