JamesM wrote:Could you please post a dissassembly of the resulting function?
and just grab where the function is.
This is better:
Code: Select all
objdump -S kernel.elf | c++filt
memmgr::_flush_gdt(gdtdesc& gdtr)
10124a: 55 push %ebp
10124b: 89 e5 mov %esp,%ebp
10124d: 83 ec 10 sub $0x10,%esp
{
int *p=reinterpret_cast<int*>(&gdtr);
101250: 8b 45 0c mov 0xc(%ebp),%eax
101253: 89 45 fc mov %eax,-0x4(%ebp)
asm("lgdt %0" : : "m"(*p));
101256: 8b 45 fc mov -0x4(%ebp),%eax
101259: 0f 01 10 lgdtl (%eax)
asm("movw %0, %%ds\n\t"
"movw %1, %%es\n\t"
"movw %2, %%ss"
: /* no output */
: "r"(ds), "r"(es), "r"(ss)
);
10125c: 0f b7 0d 36 00 20 00 movzwl 0x200036,%ecx
101263: 0f b7 15 38 00 20 00 movzwl 0x200038,%edx
10126a: 0f b7 05 34 00 20 00 movzwl 0x200034,%eax
101271: 8e d9 mov %ecx,%ds
101273: 8e c2 mov %edx,%es
101275: 8e d0 mov %eax,%ss
asm("ljmp $0x8, $1f\n"
"1:\n"
: : "r"(cs)
);
101277: 0f b7 05 32 00 20 00 movzwl 0x200032,%eax
10127e: ea 85 12 10 00 08 00 ljmp $0x8,$0x101285
// test doing leave stuff manually to see what happens to ebp
asm("movl %ebp, %esp\n\t"
"movl (%esp), %edi\n\t"
"mov %edi, %ebp");
101285: 89 ec mov %ebp,%esp
101287: 8b 3c 24 mov (%esp),%edi
10128a: 89 fd mov %edi,%ebp
}
10128c: c9 leave
10128d: c3 ret
[/quote]
I'm a little confused by the syntax here:
Code: Select all
asm("ljmp $0x8, $1f\n"
"1:\n"
: : "r"(cs)
);
That seems to be to be jumping to the CS 0x8, and location 0x1f (note the $ prefix = immediate). I may be wrong (I use intel syntax normally) - but post the dissassembly anyway so we can see what the compiler is doing
Yes, that's for loading CS - but that's not the problem (that I know of, anyway). I'm beginning to think it's actually that there is a 0 in my stack, but gdb is misleading me. (FWIW, bochs also thinks there's not a zero in (%esp)). Could there be something wrong with my stack segment? Here it is:
Code: Select all
struct __attribute__ ((packed)) segdesc
{
unsigned int limit0:16;
unsigned int base0:16;
unsigned int base1:8;
unsigned int type:4;
unsigned int sflag:1;
unsigned int priv:2;
unsigned int pflag:1;
unsigned int limit1:4;
unsigned int avail:1;
unsigned int lflag:1;
unsigned int dub:1;
unsigned int gran:1;
unsigned int base2:8;
};
segdesc gdt[] __attribute__ ((aligned(8))) =
{
// null descriptor
/* 0x0 */ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
// code descriptor for kernel [0x0 - 0x200000] (really only 1MiB
// for xok, but no reason to segment off the first 1MiB)
/* 0x08 */ {0x0200, 0x0000, 0x00, 0xa, 1, 0, 1, 0, 0, 0, 1, 1, 0},
// stack descriptor (512KB, growing down)
/* 0x10 */ {0x0080, 0x0000, 0x28, 0x6, 1, 0, 1, 0, 0, 0, 1, 1, 0},
// heap descriptor
/* 0x18 */ {0x0400, 0x0000, 0x28, 0x2, 1, 0, 1, 0, 0, 0, 1, 1, 0},
// extra data descriptor for < 0x100000
/* 0x20 */ {0x0100, 0x0000, 0x00, 0x2, 1, 0, 1, 0, 0, 0, 1, 1, 0}
};
uint16_t gdt_limit = 0x27; // 8n - 1
uint16_t cs = 0x8; // 0..001000
uint16_t ss = 0x10; // 0..010000
uint16_t ds = 0x18; // 0..011000
uint16_t es = 0x20; // 0..100000