Page 1 of 1
how to mix nasm and C++
Posted: Fri Aug 29, 2008 8:05 am
by xDDunce
ok,
so i finally got my kernel working with classes, although so far all i have is a screen driver.
i am now trying to create the GDT and this requires using some assembly but i can't quite get it right. i suppose the easiest way would be to use the asm() within my gdt_flush() but i haven't had any luck with it. any ideas?
thanks in advance!
James.
Re: how to mix nasm and C++
Posted: Fri Aug 29, 2008 8:30 am
by albeva
show us your code. And yes you do require a bit of assembly when setting GDT and a far jump as well.
Code: Select all
; Load the gdt.
; void gdt_load (gdt_ptr_t *);
_gdt_load:
mov eax, [esp+4]
lgdt [eax]
mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
jmp 0x08:flush2
flush2:
ret
Re: how to mix nasm and C++
Posted: Fri Aug 29, 2008 8:33 am
by DeletedAccount
Re: how to mix nasm and C++
Posted: Fri Aug 29, 2008 8:36 am
by souradipm
C++ mangles the names of your functions, so calling them is a lengthy process
Not really, but you need to work out how C++ mangles it. I would tell you, but I use C, so I don't know. However, I know some people here do know. An alternative is to use inline assembly, but I'm not too familiar with AT&T syntax. I guess you could use .intel_syntax noprefix
Re: how to mix nasm and C++
Posted: Fri Aug 29, 2008 9:34 am
by AJ
The main caveat, as souradipm says is name mangling. You can get around this by declaring your asm function prototype as extern "C" (e.g. "extern "C" void myasmfunction()" ).
Really, though, we need more specific info about why things don't work - what errors are you getting (I assume they are compiler errors).
Cheers,
Adam
Re: how to mix nasm and C++
Posted: Fri Aug 29, 2008 10:40 am
by xDDunce
The main caveat, as souradipm says is name mangling. You can get around this by declaring your asm function prototype as extern "C" (e.g. "extern "C" void myasmfunction()" ).
the compiler does not like to define external functions within a class so that rules that out.
my code:
GDT.C
Code: Select all
#include "../includes/generics.h"
GDT::GDT(){
}
void GDT::GDT_set_gate(int num, unsigned long base, unsigned long limit, unsigned char access, unsigned char gran)
{
gdt[num].base_low = (base & 0xFFFF);
gdt[num].base_middle = (base >> 16) & 0xFF;
gdt[num].base_high = (base >> 24) & 0xFF;
gdt[num].limit_low = (limit & 0xFFFF);
gdt[num].granularity = ((limit >> 16) & 0x0F);
gdt[num].granularity |= (gran & 0xF0);
gdt[num].access = access;
}
void GDT::GDT_Install()
{
gp.limit = (sizeof(struct gdt_entry) * 3) - 1;
gp.base = (unsigned int) &gdt;
GDT_set_gate(0, 0, 0, 0, 0);
GDT_set_gate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF);
GDT_set_gate(2, 0, 0xFFFFFFFF, 0x92, 0xCF);
GDT_Flush();
}
void GDT::GDT_Flush(){
}
GDT::~GDT(){
}
generics.h
Code: Select all
#ifndef generics__h_____
#define generics__h_____
#define BLACK 0x00
#define BLUE 0x01
#define GREEN 0x02
#define CYAN 0x03
#define RED 0x04
#define MAGENTA 0x05
#define BROWN 0x06
#define LIGHT_GREY 0x07
#define DARK_GREY 0x08
#define LIGHT_BLUE 0x09
#define LIGHT_GREEN 0x0A
#define LIGHT_CYAN 0x0B
#define LIGHT_RED 0x0C
#define LIGHT_MAGENTA 0x0D
#define LIGHT_BROWN 0x0E
#define WHITE 0x0F
class Screen{
public:
Screen();
~Screen();
void cls();
void update_csr();
void puts(const char * string);
void putch(char c);
void scroll();
void settextcolor(unsigned char forecolor,unsigned char backcolor);
private:
int csr_x, csr_y;
unsigned char attrib;
unsigned char *videomem;
};
extern unsigned char inb(unsigned short port);
extern void outb(unsigned short port, unsigned char value);
struct gdt_entry
{
unsigned short limit_low;
unsigned short base_low;
unsigned char base_middle;
unsigned char access;
unsigned char granularity;
unsigned char base_high;
} __attribute__((packed));
struct gdt_ptr
{
unsigned short limit;
unsigned int base;
} __attribute__((packed));
class GDT{
public:
GDT();
~GDT();
void GDT_Install();
void GDT_Flush();
void GDT_set_gate(int num, unsigned long base, unsigned long limit, unsigned char access, unsigned char gran);
private:
struct gdt_entry gdt[3];
struct gdt_ptr gp;
};
#endif
James.
Re: how to mix nasm and C++
Posted: Fri Aug 29, 2008 12:31 pm
by xDDunce
i ended up using a work around for this, just for simplicity. although if anyone has worked out a way around the "extern "C"{}" statements, please could you let me know?
thanks for all the help!
James.
Re: how to mix nasm and C++
Posted: Fri Aug 29, 2008 12:48 pm
by AJ
A function pointer as a member variable? I think wrapping an extern "C" call in a member function is tidier, though.
Cheers,
Adam
Re: how to mix nasm and C++
Posted: Fri Aug 29, 2008 3:51 pm
by bewing
To deal with mangling -- you don't try to figure it out in advance.
You compile the code without any asm. The linker tells you the mangled names of all the "unresolved reference"d functions. Then you add those names into your asm as labels, and recompile.
Re: how to mix nasm and C++
Posted: Sun Aug 31, 2008 7:34 am
by xDDunce
thanks berkus! that is what i ended up doing. but thanks for the suggestion anyway.
James.