delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1998/05/10/04:42:28

From: "Rob van Berkel" <rvberkel AT EuroNet DOT NL>
To: <djgpp AT delorie DOT com>
Subject: HELP: using ASM LCALL keeps resulting in SIGSEGV
Date: Sun, 10 May 1998 10:34:49 +0200
Message-ID: <000001bd7bee$7e93f2e0$0201a8c0@king>
MIME-Version: 1.0
Importance: Normal

Hi
(Sorry for the repost but on the previous one i forgot the subject.)
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
// might as well just create a clean one - no difference
bios32_cs_sel = __dpmi_create_alias_descriptor(_my_cs())
__dpmi_set_segment_base_address(bios32_cs_sel, mi.address)
__dpmi_set_segment_limit(bios32_cs_sel, mi.size - 1)
// setup for 1bit granularity, non-system, readable code segment
__dpmi_set_descriptor_access_rights(bios32_cs_sel,0x40fa)
        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)" // here's where the SIGSEV happens
                : "=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