Page 1 of 2

Assembly and C++ working together

Posted: Mon Oct 26, 2009 3:02 am
by chibicitiberiu
Hello,
I'm not very good at programming operating systems, I'm just a begginner, but based on tutorials on the wiki I managed to make an advanced 'hello world' OS, which has a function to display strings of text on the screen and another function to display styled text on the screen. And I also managed to install GRUB on a floppy and just update the kernel when I edit it.

Now, many of the tutorials I found here are in assembly, but I'm not very good at it, and I want my kernel to be in C++.
How can I make a function written in Assembly that can be accessed from C++?
The two ways I thought of are:
1. in 'loader.s' make that function, and the name with a label, and just declare it in C++ as extern
2. use asm keyword in C++, but the problem is that it is not fully compatible with NASM code.
Will #1 even work? Or how can I make them?

I looked at keyboard input wiki, and I was a bit scared, it said that I have to do some other things I don't understand before trying to implement keyboard input. And it was all assembly, and not C.
Help?

Re: Assembly and C++ working together

Posted: Mon Oct 26, 2009 3:19 am
by Mikoskay
First way is the proper way. However I recommend you declaring it as extern "C" which just works better for me in some cases.

But I got more difficult question to someone wiser than both of us. :P How to call C++ function hidden in namespace (or eg. a method of a class) from assembler? I've been googling for an hour by now and still no answer. Is it just impossible?

Re: Assembly and C++ working together

Posted: Mon Oct 26, 2009 3:26 am
by chibicitiberiu
Mikoskay wrote:First way is the proper way. However I recommend you declaring it as extern "C" which just works better for me in some cases.

But I got more difficult question to someone wiser than both of us. :P How to call C++ function hidden in namespace (or eg. a method of a class) from assembler? I've been googling for an hour by now and still no answer. Is it just impossible?
Well, make a function outside that namespace that calls the one inside the namespace and call that one from assembler.

and BTW, what will "C" do?

Re: Assembly and C++ working together

Posted: Mon Oct 26, 2009 3:36 am
by Mikoskay
chibicitiberiu wrote:
Mikoskay wrote:First way is the proper way. However I recommend you declaring it as extern "C" which just works better for me in some cases.

But I got more difficult question to someone wiser than both of us. :P How to call C++ function hidden in namespace (or eg. a method of a class) from assembler? I've been googling for an hour by now and still no answer. Is it just impossible?
Well, make a function outside that namespace that calls the one inside the namespace and call that one from assembler
I thought about it, but it's just a mere (and quite ugly) palliative. Are you sure there's no better way?
chibicitiberiu wrote:and BTW, what will "C" do?
It forces compiler to compile the function in clear C. It, for example, disables function overloading, which could make some problems used with assembly.

Re: Assembly and C++ working together

Posted: Mon Oct 26, 2009 4:01 am
by AJ
But I got more difficult question to someone wiser than both of us. :P How to call C++ function hidden in namespace ...
Well, make a function outside that namespace that calls the one inside the namespace and call that one from assembler
Alternatively, compile the binary, objdump it, note down the mangled function name and call that.
chibicitiberiu wrote:and BTW, what will "C" do?
It forces compiler to compile the function in clear C. It, for example, disables function overloading, which could make some problems used with assembly.
In addition to disabling function overloading, it prevents name mangling (which is, of course, related to overloading - if overloaded function names were not mangled, you'd get conflicting symbols).

Cheers,
Adam

Re: Assembly and C++ working together

Posted: Mon Oct 26, 2009 4:52 am
by chibicitiberiu
And another question, how do I return a value to C++ from assembly? For example to get a keyboard input, i need to return an ascii character (or two in case of special chars).
From the assembly I know, 'ret' doesn't have parameters.

And can C++ look in the assembler registries, eax, ebx and all those?

Re: Assembly and C++ working together

Posted: Mon Oct 26, 2009 5:19 am
by AJ
Hi,

I strongly suggest that you read the System V ABI. If you are going to be mixing a HLL and ASM, its pretty essential reading. It will tell you, for example, which registers are "scratch" registers and which registers to save. It will also answer your other questions about returning values (FYI, you normally return <=32 bit values in eax, <=64 bit values in eax:edx and structures on the stack, but the 64 bit calling conventions are very different and you have 8 more GP registers to deal with).

I also have it on good authority that there will soon be a full wiki article on this topic :)

Cheers,
Adam

Re: Assembly and C++ working together

Posted: Mon Oct 26, 2009 9:50 am
by Mikoskay
I've just found something interesting on a topic I've never seen before: http://redir.no-ip.org/mirrors/my.execp ... /index.htm. IMHO most interesting is a linker script.

edit

Still searching... I've been gathering informations about implementing C++ ABI, and I've found answer on my question about calling C++ functions from assembler. This manual needs no explanation: http://www.codesourcery.com/public/cxx- ... l#mangling.

Re: Assembly and C++ working together

Posted: Tue Oct 27, 2009 3:08 am
by chibicitiberiu
Now I tried to make a function like this, but I get a linker error:
kernel.o:(.eh_frame+0x11): undefined reference to `__gxx_personality_v0'

Here is a source code:
kernel.cpp

Code: Select all

extern "C" void _main (struct multiboot_data* mbd, unsigned int magic);
extern "C" int number();

unsigned char *videoram = (unsigned char*) 0xb8000;

void ctamain();
void cout(const char string[]);
void cout_style (const char string[], unsigned char style);
void cls();

void _main (struct multiboot_data* mdb, unsigned int magic)
{
	if (magic != 0x2BADB002)
	{
		cout ("Magic error. System halted!");
	}

	char* boot_loader_name = (char*) ((long*)mdb)[16];

	ctamain();
}

void cls()
{
	int i;
	for (i = 0; i <= 80*25; i++)
	{
		videoram[i*2] = 0;
		videoram[i*2+1] = 0;
	}
}

void cout (const char string[])
{
	int offset=0, i;
	while (videoram[offset*2]!=0) offset++;

	for (i=0; string[i]!=0; i++, offset++) {
		if (string[i] == '\n')
			do {  videoram[offset*2] = ' ';
			      offset++;
			} while (offset%80 != 0);
			
		else {
		videoram[offset*2] = string[i];
		videoram[offset*2+1] = 0x07;
		}
	}
}

void cout_style (const char string[], unsigned char style)
{
	int offset=0, i;
	while (videoram[offset*2]!=0) offset++;

	for (i=0; string[i]!=0; i++, offset++) {
		if (string[i] == '\n')
			do {  videoram[offset*2] = ' ';
			      videoram[offset*2+1] = style;
			      offset++;
			} while (offset%80 != 0);
			
		else {
		videoram[offset*2] = string[i];
		videoram[offset*2+1] = style;
		}
	}
}


void ctamain()
{
	int no = number();
	char whatever[] = "   is a number.\n";
	whatever[0] = '0' + (char) (no/10);
	whatever[1] = '0' + (char) no;

	cls();
	cout("Hello, world!!!\n");
	cout("Welcome to CTA OS 1.0\n");
	cout_style("MUHAHAHAHAHAHAHAHAHSfdHAHAHA\n", 0x1F);
	cout(whatever);
	cout("Good bye now.");
}
loader.s

Code: Select all

global loader
global number
extern _main
extern start_ctors, end_ctors, start_dtors, end_dtors

MODULEALIGN equ 1<<0
MEMINFO     equ 1<<1
FLAGS       equ MODULEALIGN | MEMINFO
MAGIC       equ 0x1BADB002
CHECKSUM    equ -(MAGIC+FLAGS)

section .text
align 4
MultiBootHeader:
	dd MAGIC
	dd FLAGS
	dd CHECKSUM

STACKSIZE equ 0x4000

loader:
	mov esp, stack+STACKSIZE
	push eax
	push ebx

static_ctors_loop:
	mov ebx, start_ctors
	jmp .test
.body:
	call [ebx]
	add ebx, 4
.test:
	cmp ebx, end_ctors
	jb .body

	call _main

static_dtors_loop:
	mov ebx, start_dtors
	jmp .test
.body:
	call [ebx]
	add ebx, 4
.test:
	cmp ebx, end_dtors
	jb .body

hang:
	hlt
	jmp hang

number:
	mov eax, 12
	ret

section .bss
align 4
stack:
	resb STACKSIZE

Re: Assembly and C++ working together

Posted: Tue Oct 27, 2009 3:15 am
by gravaera
Hi:

__gxx_personality_v0 is a symbol linked in by GCC according to the C++ ABI, and if I remember correctly, it has to do with C++ exceptions.

Add '-fno-exceptions' to your GCC command line.

Re: Assembly and C++ working together

Posted: Tue Oct 27, 2009 3:32 am
by chibicitiberiu
gravaera wrote:Hi:

__gxx_personality_v0 is a symbol linked in by GCC according to the C++ ABI, and if I remember correctly, it has to do with C++ exceptions.

Add '-fno-exceptions' to your GCC command line.
Thanks, that fixed it.

Re: Assembly and C++ working together

Posted: Tue Oct 27, 2009 5:05 am
by Mikoskay
I recommend you reading C++ ABI description (http://www.codesourcery.com/public/cxx-abi/abi.html) and some of dialect controlling options from GCC manual (http://gcc.gnu.org/onlinedocs/gcc/C_002 ... tions.html). It really makes topic more clear.

Re: Assembly and C++ working together

Posted: Fri Nov 06, 2009 8:24 am
by JamesM
chibicitiberiu wrote:
gravaera wrote:Hi:

__gxx_personality_v0 is a symbol linked in by GCC according to the C++ ABI, and if I remember correctly, it has to do with C++ exceptions.

Add '-fno-exceptions' to your GCC command line.
Thanks, that fixed it.
Check the C++ wiki article. It has the answers to all your questions. Please check the wiki first before asking, I KNOW it's easier to ask, but we didn't go through all that effort for nothing. Your time is not more valuable than ours. :-)

Thank you! </PSA>

Re: Assembly and C++ working together

Posted: Sat Nov 07, 2009 2:57 pm
by chibicitiberiu
JamesM wrote:
chibicitiberiu wrote:
gravaera wrote:Hi:

__gxx_personality_v0 is a symbol linked in by GCC according to the C++ ABI, and if I remember correctly, it has to do with C++ exceptions.

Add '-fno-exceptions' to your GCC command line.
Thanks, that fixed it.
Check the C++ wiki article. It has the answers to all your questions. Please check the wiki first before asking, I KNOW it's easier to ask, but we didn't go through all that effort for nothing. Your time is not more valuable than ours. :-)

Thank you! </PSA>
It wasn't clear to me, mainly the first question, and I asked before that article was written.

Re: Assembly and C++ working together

Posted: Sat Nov 07, 2009 5:03 pm
by Combuster
chibicitiberiu wrote:and I asked before that article was written.
If you plan on getting on the bad side of everybody, then telling lies is the way to go. :roll: