Page 1 of 1

[Solved]Inline assembler

Posted: Fri Aug 31, 2012 12:48 am
by leyley
I'm writing a C function that uses inline assembler to move data into a memory, but it doesn't work. How can I solve this problem?
Thanks!

Code: Select all

/* Output a charactor; 32bits protected mode; */
void __putc(unsigned short x,unsigned short y,unsigned char c,unsigned char s){
	unsigned int p=(y*0x50+x)*2;
	unsigned short ax=s|(c<<8);
	__asm__ __volatile__("movl $0xb8000,%%ecx\n\t"
	"addl %0,%%ecx\n\t"
	"movw %1,%%ax\n\t"
	"movw %%ax,(%%ecx)"::"b"(p),"d"(ax));
}

Re: Inline assembler

Posted: Fri Aug 31, 2012 1:04 am
by iansjack
Look at the generated code. It should then be obvious what is going wrong.

Re: Inline assembler

Posted: Fri Aug 31, 2012 1:06 am
by Combuster
It actually works for me. Although using assembler in this fashion is rather pointless - it's slower than it's equivalent C code.

Re: Inline assembler

Posted: Fri Aug 31, 2012 1:13 am
by leyley
Combuster wrote:It actually works for me. Although using assembler in this fashion is rather pointless - it's slower than it's equivalent C code.
Yep, I use it to store the data into registers to test... How can you did it? Would you give me some information about your developing configuration? thanks.
I'm using a DELL e5420 with Archlinux x86_64, all of my software has its lastest version in the official repo.
The simulator is Virtualbox and bochs.
Thanks!

Re: Inline assembler

Posted: Fri Aug 31, 2012 3:32 am
by Combuster

Re: Inline assembler

Posted: Fri Aug 31, 2012 3:51 am
by leyley
Combuster wrote:GCC Cross-Compiler
Maybe the reason why it doesn't work for me is the 64bits arch of my host?
I will try to compile them at a 32bits guest system...

Re: Inline assembler

Posted: Sun Sep 02, 2012 8:32 pm
by leyley
After using 32bits gcc & ld, it finally works!
When I compilied the C source with -S option(output assembler), I've found that the 64bits environment will add a 'cltq' instrument at the end of movs.

Code: Select all

void __putc(unsigned short x,unsigned short y,unsigned char c,unsigned char s){
	unsigned int *p=0xb8000+(y*0x50+x)*2;
	unsigned short ax=s|(c<<8);
	(*p)=ax;
}