Re: mixing C and assembly.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Salim,

While there aren't any specific tutorials for your processor that I know of,
there as various one out there for x86.  Learning the GCC style syntax, you
shuold be able to easily translate that for ur processor.  I personally just
went through the process of learning GCC inline assembler, and it works beautifully.

I'll disect Joel's example with references to online manuals just to help you
out.  Refer to the GCC manual:

http://gcc.gnu.org/onlinedocs/gcc-3.3.1/gcc/Extended-Asm.html#Extended%20Asm
Here's my learning site:
http://www.delorie.com/djgpp/doc/brennan/brennan_att_inline_djgpp.html

1> #define _CPU_ISR_Disable( _isr_cookie ) \
2>    { register unsigned int _disable_mask = PPC_MSR_DISABLE_MASK; \
3>      _isr_cookie = 0; \
4>      asm volatile ( \
5>          "mfmsr %0; andc %1,%0,%1; mtmsr %1" : \
6>          "=&r" ((_isr_cookie)), "=&r" ((_disable_mask)) : \
7>          "0" ((_isr_cookie)), "1" ((_disable_mask)) \
8>          ); \
9>    }

Line 1 creates a define.  This is really just for convenience.  You could just
type this stuff inline, but like Joel, I also used defines as those are the
examples I saw on the net.

Lines 2 and 3 and just plain C code....nothing special.

Line 4 is the beginning of the asm routine.  I tended to use __asm__
__volatile__ , but skipping the __ works as well.

Line 5 is the actual assembler code.  Assuming you know the instruction set for
your processor, there should be nothing too special here.  Just remember GCC
inline assembler is specifed as: <instruction> <source> <destination>.  I had
previously coded intel assembler, which is the reverse, but I got used to this
syntax very quickly.  Now, you may be wondering what the hell is %1 and %0...

This is something I will call assigning registers to variables.  This is a nice
way of interfacing C and asm.

Line 6 specifies the input registers.  GCC will copy the value of all inputs to
their respective registers PRIOR to executing any of your specified assembler
code.  In the assmebler body (on line 5), they are then referred to in numerical
order starting at %0, then %1, %2...So in the above example, %0 'refers' to the
register copy of _isr_cookie.  %1 referes to the register copy of _disable_mask.

The "=&r" is specific to ur processor.  This specifies what kind of register
should be used as a copy for the C variable.  I don't know where to look this
up, but check the GCC manual.  I think this above just means to let GCC choose
any register.

Line 7 specfies the output registers.  Here, AFTER your asm code has executed,
the values from the register will then be copied to their C variables.  Once
again they are referred to by number.  Keep in mind here, that the numbering
continues for the input registers.  So normally, if there were 2 input
registers( %0 and %1), the first output paramter would be referenced by %2.
However, in this particular example, _isr_cookie and _disable_mask are used as
both input and output parameters.  So it is just specified that %0 still refers
to _isr_cookie's register copy and %1 still refers to _disable_mask's register copy.

There can be one more line after these two specifiers known as the 'clobbered'
list.  This is a list of registers/memory that has changed in the asm code.  It
also needs to have a colon prefix it, so if we wanted to have one for this
example, line 7 would become.
"0" ((_isr_cookie)), "1" ((_disable_mask)) : \

Then line 8 would specify all registers/memory that has changed in the asm code.
   For example, if you peform a write to memory, you would modify(clobber)
memory.  So you would specify that by typing
8> "memory" ); \

Or if you modified some other register.  I don't know PPC register names, but
say it had register r7 and you modified it as well.  Then you would have.
8> "memory", "%r7" ); \ 

And that's basically it.  That should get your by.
have fun,


Yamin


Quoting Joel Sherrill <joel.sherrill@xxxxxxxxxxx>:

> Salim Belgroune wrote:
> 
> > Hello,
> > 
> > I'm currently using the MPC8260  ( with a PPC 603e core ).
> > 
> > Could you give me a tutorial or examples on writing assembly routines 
> > that will be written and compiled inside a C source code.
> 
> There are no tutorials that I know of.  There are sources for examples
> including the PowerPC specific code in RTEMS.  Here is an example
> of disabling external interrupts via the MSR:
> 
> #define _CPU_ISR_Disable( _isr_cookie ) \
>    { register unsigned int _disable_mask = PPC_MSR_DISABLE_MASK; \
>      _isr_cookie = 0; \
>      asm volatile ( \
>          "mfmsr %0; andc %1,%0,%1; mtmsr %1" : \
>          "=&r" ((_isr_cookie)), "=&r" ((_disable_mask)) : \
>          "0" ((_isr_cookie)), "1" ((_disable_mask)) \
>          ); \
>    }
> 
> It returns the previous value of the MSR as "_isr_cookie" so you
> can enable later to the previous level:
> 
> #define _CPU_ISR_Enable( _isr_cookie )  \
>    { \
>       asm volatile ( "mtmsr %0" : \
>                     "=r" ((_isr_cookie)) : \
>                     "0" ((_isr_cookie))); \
>    }
> 
> There are lots of other examples in the RTEMS source.
> 
> > Kind regards.
> > 
> > Salim Belgroune.
> > 
> 
> 
> -- 
> Joel Sherrill, Ph.D.             Director of Research & Development
> joel@xxxxxxxxxxx                 On-Line Applications Research
> Ask me about RTEMS: a free RTOS  Huntsville AL 35805
> Support Available                (256) 722-9985
> 




----------------------------------------
This mail sent through www.mywaterloo.ca

[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux