Page 1 of 1

Problem about asm in C

Posted: Thu Feb 28, 2008 5:04 am
by Jeko
I have this function (I use this to handle irqs):

Code: Select all

void pic_handler()
{
	asm(".globl pic_handler\n"
	"pic_handler:\n"
	"cli\n"

	"pusha\n"
	"pushl %ds\n"
	"pushl %es\n"
	"pushl %fs\n"
	"pushl %gs\n"

	"movl %esp, %eax\n"
	"pushl %eax\n"

	"call exec_irq\n"

	"popl %eax\n"
	"mov %eax, %esp\n"

	"popl %gs\n"
	"popl %fs\n"
	"popl %es\n"
	"popl %ds\n"
	"popa\n"
	"sti\n"
	"iret\n");
}
But when I compile there is an error message:

Code: Select all

ccache gcc -Wall -O -floop-optimize2 -fno-builtin -nostdlib -nostartfiles -nodefaultlibs -nostdinc -I include -ffreestanding -fno-stack-protector -c kernel/pic.c -o kernel/pic.o
/tmp/ccUu4Ddw.s: Assembler messages:
/tmp/ccUu4Ddw.s:10: Error: symbol `pic_handler' is already defined
make: *** [kernel/pic.o] Error 1
How can I resolve this?

PS: Is the code correct or I must change something?

Posted: Thu Feb 28, 2008 6:08 am
by os.hacker64
looks like you have a function with the same name in a .s file.

Posted: Thu Feb 28, 2008 6:20 am
by Jeko
os.hacker64 wrote:looks like you have a function with the same name in a .s file.
Sorry, but I'm compiling only a file...
ccache gcc -Wall -O -floop-optimize2 -fno-builtin -nostdlib -nostartfiles -nodefaultlibs -nostdinc -I include -ffreestanding -fno-stack-protector -c kernel/pic.c -o kernel/pic.o

So, it's impossible that the error is this...

However I think the error is due to:

Code: Select all

void pic_handler()
{
   asm(".globl pic_handler\n"
   "pic_handler:\n"
   "cli\n"

   "pusha\n"
   "pushl %ds\n"
   "pushl %es\n"
   "pushl %fs\n"
   "pushl %gs\n"

   "movl %esp, %eax\n"
   "pushl %eax\n"

   "call exec_irq\n"

   "popl %eax\n"
   "mov %eax, %esp\n"

   "popl %gs\n"
   "popl %fs\n"
   "popl %es\n"
   "popl %ds\n"
   "popa\n"
   "sti\n"
   "iret\n");
} 
This. Because the function in C is called pic_handler, and in asm the global function is called pic_handler.
If I want to insert a asm function into a C file, how can I do?

Posted: Thu Feb 28, 2008 6:38 am
by JamesM
You're right, it is because the C function has the same name as the label you want defined.
You can dispense with the function wrapper, iirc, I believe inline asm can be put anywhere in a source file.

If not, then call the function something different so as not to clash.

Posted: Thu Feb 28, 2008 6:47 am
by pini
.. or you could just remove your first two lines of inline asm.

Posted: Thu Feb 28, 2008 6:51 am
by JamesM
pini wrote:.. or you could just remove your first two lines of inline asm.
But then he would end up with the function preamble, which I assume he doesn't want.

Posted: Thu Feb 28, 2008 7:06 am
by pini
correct!
The cleanest way is to use a simple asm wrapper to call handling C code.

Posted: Thu Feb 28, 2008 7:10 am
by Jeko
JamesM wrote:I believe inline asm can be put anywhere in a source file.
No. Without void pic_handler():

Code: Select all

asm(".globl pic_handler\n"
	"pic_handler:\n"
	"cli\n"
	"pusha\n"
	"pushl %ds\n"
	"pushl %es\n"
	"pushl %fs\n"
	"pushl %gs\n"

	"movl %esp, %eax\n"
	"pushl %eax\n"

	"call exec_irq\n"

	"popl %eax\n"
	"mov %eax, %esp\n"

	"popl %gs\n"
	"popl %fs\n"
	"popl %es\n"
	"popl %ds\n"
	"popa\n"
	"sti\n"
	"iret\n");
I have this error message:

Code: Select all

kernel/pic.c: In function ‘init_pic’:
kernel/pic.c:133: error: ‘pic_handler’ undeclared (first use in this function)
kernel/pic.c:133: error: (Each undeclared identifier is reported only once
kernel/pic.c:133: error: for each function it appears in.)
make: *** [kernel/pic.o] Error 1
pini wrote:correct!
The cleanest way is to use a simple asm wrapper to call handling C code.
How?

Posted: Thu Feb 28, 2008 9:18 am
by JamesM
MarkOS wrote:
JamesM wrote:I believe inline asm can be put anywhere in a source file.
No. Without void pic_handler():

Code: Select all

asm(".globl pic_handler\n"
	"pic_handler:\n"
	"cli\n"
	"pusha\n"
	"pushl %ds\n"
	"pushl %es\n"
	"pushl %fs\n"
	"pushl %gs\n"

	"movl %esp, %eax\n"
	"pushl %eax\n"

	"call exec_irq\n"

	"popl %eax\n"
	"mov %eax, %esp\n"

	"popl %gs\n"
	"popl %fs\n"
	"popl %es\n"
	"popl %ds\n"
	"popa\n"
	"sti\n"
	"iret\n");
I have this error message:

Code: Select all

kernel/pic.c: In function ‘init_pic’:
kernel/pic.c:133: error: ‘pic_handler’ undeclared (first use in this function)
kernel/pic.c:133: error: (Each undeclared identifier is reported only once
kernel/pic.c:133: error: for each function it appears in.)
make: *** [kernel/pic.o] Error 1
pini wrote:correct!
The cleanest way is to use a simple asm wrapper to call handling C code.
How?
That's fine, you just have to declare pic_handler as extern as well, so you can access it from C:

Code: Select all

extern void pic_handler(void);

Posted: Thu Feb 28, 2008 9:49 am
by Jeko
JamesM wrote:That's fine, you just have to declare pic_handler as extern as well, so you can access it from C:

Code: Select all

extern void pic_handler(void);
Thank you very much

Posted: Thu Feb 28, 2008 9:54 am
by JamesM
de rien.