GDT: mov ss, ax in ASM code causing a triple fault, Advice?
Posted: Tue Jul 28, 2009 2:10 pm
Hi, I seem to be getting a triple fault which I can't find any obvious cause for, I've narrowed it down to a single instruction but it still eludes solvation (Nice wording D:)
anyhow This is the ASM code I am using for the GDTFlush Commonly seen in many tutorials:
And the C++ Code I am using to call it is in the form of this class:
Header:
Code:
The bochs log shows me that ss did indeed get set to 0x10 (Value of AX).
The one thing that sticks out to me is "base" is ffffffff while it should be 00000000?
Sorry If this is a really dumb thing but it's had me stumped for a few hours now and I've looked all over the net and within my code to unreavel it's secrets!
anyhow This is the ASM code I am using for the GDTFlush Commonly seen in many tutorials:
Code: Select all
[GLOBAL GDTFlush] ; Allows the C code to call gdt_flush().
GDTFlush:
mov eax, [esp+4] ; Get the pointer to the GDT, passed as a parameter.
lgdt [eax] ; Load the new GDT pointer
mov ax, 0x10 ; 0x10 is the offset in the GDT to our data segment
mov ds, ax ; Load all data segment selectors
mov es, ax
mov fs, ax
mov gs, ax
;hlt
mov ss, ax ; FAULT HAPPENS ON THIS
;hlt
jmp 0x08:.flush ; 0x08 is the offset to our code segment: Far jump!
.flush:
ret
Header:
Code: Select all
#ifndef GDT_H
#define GDT_H
#include "system.h"
struct GDTEntry
{
u16int limit_low;
u16int base_low;
u8int base_middle;
u8int access;
u8int granularity;
u8int base_high;
} __attribute__((packed));
struct GDTptr
{
u16int limit;
u8int base;
} __attribute__((packed));
extern "C" { void GDTFlush(u32int pointer); };
class GDT
{
private:
struct GDTEntry GDT_Entries[5];
struct GDTptr GDT_Ptr;
void set_gate(s32int num, u32int base, u32int limit, u8int access, u8int gran);
public:
GDT();
~GDT();
};
#endif
Code: Select all
#include "GDT.h"
GDT::GDT()
{
GDT_Ptr.limit = (sizeof(GDTEntry) * 5) - 1;
GDT_Ptr.base = (u32int)&GDT_Entries;
set_gate(0, 0, 0, 0, 0); // Null segment
set_gate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF); // Code segment
set_gate(2, 0, 0xFFFFFFFF, 0x92, 0xCF); // Data segment
set_gate(3, 0, 0xFFFFFFFF, 0xFA, 0xCF); // User mode code segment
set_gate(4, 0, 0xFFFFFFFF, 0xF2, 0xCF); // User mode data segment
GDTFlush((u32int)&GDT_Ptr);
}
GDT::~GDT()
{
}
void GDT::set_gate(s32int num, u32int base, u32int limit, u8int access, u8int gran)
{
GDT_Entries[num].base_low = (base & 0xFFFF);
GDT_Entries[num].base_middle = (base >> 16) & 0xFF;
GDT_Entries[num].base_high = (base >> 24) & 0xFF;
GDT_Entries[num].limit_low = (limit & 0xFFFF);
GDT_Entries[num].granularity |= gran & 0xF0;
GDT_Entries[num].access = access;
}
Code: Select all
...
00013371786i[CPU0 ] | RAX=0000000000060010 RBX=0000000000102000
...
00013371786i[CPU0 ] | SEG sltr(index|ti|rpl) base limit G D
00013371786i[CPU0 ] | CS:0008( 0001| 0| 0) 00000000 000fffff 1 1
00013371786i[CPU0 ] | DS:0010( 0002| 0| 0) ffffffff 000fffff 1 1
00013371786i[CPU0 ] | SS:0010( 0002| 0| 0) 00000000 000fffff 1 1
00013371786i[CPU0 ] | ES:0010( 0002| 0| 0) ffffffff 000fffff 1 1
00013371786i[CPU0 ] | FS:0010( 0002| 0| 0) ffffffff 000fffff 1 1
00013371786i[CPU0 ] | GS:0010( 0002| 0| 0) ffffffff 000fffff 1 1
Sorry If this is a really dumb thing but it's had me stumped for a few hours now and I've looked all over the net and within my code to unreavel it's secrets!