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 -