Help-Site Computer Manuals
Software
Hardware
Programming
Networking
  Algorithms & Data Structures   Programming Languages   Revision Control
  Protocols
  Cameras   Computers   Displays   Keyboards & Mice   Motherboards   Networking   Printers & Scanners   Storage
  Windows   Linux & Unix   Mac

Inline::ASM
Write Perl Subroutines in assembler.

Inline::ASM - Write Perl Subroutines in assembler.


NAME

Inline::ASM - Write Perl Subroutines in assembler.


SYNOPSIS


   print "9 + 16 = ", add(9, 16), "\n";

   print "9 - 16 = ", subtract(9, 16), "\n";

   use Inline ASM => 'DATA', 

              AS => 'as',

              PROTO => {add => 'int(int,int)'};

   use Inline ASM => 'DATA',

              AS => 'nasm',

              ASFLAGS => '-f elf',

              PROTO => {subtract => 'int(int,int)'};

   __END__

   __ASM__

   .text

   .globl    add

   add:      movl 4(%esp),%eax

             addl 8(%esp),%eax

             ret

   __ASM__

             GLOBAL subtract

             SECTION .text

   subtract: mov eax,[esp+4]

             sub eax,[esp+8]

             ret


DESCRIPTION

Inline::ASM allows you to write Perl subroutines in assembly language. Of course, many C compilers allow you to put assembly right in your C code, so this module does not provide any new functionality. It does, however, provide a feature most C compilers don't: you can mix different assembler syntaxes in the same file!


Using Inline::ASM

Inline::ASM is almost exactly the same as Inline::C. It makes sure the globals you requested are declared global, compiles the source code and the XS wrappers, and then creates one loadable module for each code segment.

There are some shortcomings of extending Perl with assembly. Perl is written in C (and Perl), and makes heavy use of macros to provide a consistent API when it's compiled with different options. For example, the C programmer usually doesn't care if Perl is compiled with threads or without, because the all API calls are resolved to a particular Perl interpreter using macros.

Inline::ASM tries to make your life simpler by overloading the PROTO or PROTOTYPE hints to do some menial macro processing for you. See ASM Configuration Options, below.


Function Definitions

Inline::C uses a Parse::RecDescent grammar to find function definitions in C code. Because assembler is a much simpler syntax, and both NASM and GNU AS have pseudo-ops for declaring global symbols, Inline::ASM runs your code through a regular expression to search for the pseudo-ops.

For example, in NASM, you declare global symbols like so:


           GLOBAL myfunction

   myfunction:

           mov eax,10

In GNU AS, you declare global symbols like so:


   .globl myfunction

   myfunction:

           mov $10,%eax

Inline::C gets all the information it needs from your C code. In particular, it's easy to find out what to pass a function, because the function header tells you:


   void foo(int a, char *b) { ... }

The corresponding assembler code doesn't tell you very much:


   foo:

So Inline::ASM will only bind to symbols you ask for via the PROTO option. PROTO simply gives Inline::ASM the rest of the information about the symbol. It won't make any difference to the assembler code, but it will allow Perl to bind to it.


ASM Configuration Options

For information on how to specify Inline configuration options, see Inline. This section describes the configuration options only available for Inline::ASM. All Inline and Inline::C options are also supported. See the Inline::C manpage for additional information.

AS

Specifies the assembler command to use. Can also be used to specify flags; in the case of the GASP assembler, you must specify flags here. Any flags in ASFLAGS will be passed to GNU as, rather than GASP.

ASFLAGS

Specifies flags to pass to the assembler.


Supported Assemblers

These assemblers have been tested with Inline::ASM:

  1. GNU AS

    GNU AS is a bare-bones assembler with no macro support. It works fine.

  2. GASP (GNU Assembler Preprocessor)

    GASP is a macro preprocessor designed to emit code for AS to assembler. This system works fine, except that in order to pass options to 'gasp' you must specify them in the AS configuration option, rather than ASFLAGS. The ASFLAGS are passed only to GNU as, which is automatically invoked on the output of running the GASP preprocessor.

  3. NASM (Netwide Assembler)

    NASM is an assembler with Intel syntax which works in Linux and Windows. Unfortunately,


ASM-Perl Bindings

This section describes how the `Perl' variables get mapped to `ASM' variables and back again.

Brian Ingersion (INGY@cpan.org) gives a very good description of how Perl types are translated to C types and back. That discussion is relevant to the way Inline::ASM works too, since all your variables pass through a C layer (XS) before getting to Assembler, and again on their way back to Perl. See the Inline::C manpage for that diatribe.

The biggest difference between Inline::C and Inline::ASM is that you don't get the luxury of sitting in a macro-rich C environment. You have to do some work.

The Perl API in Assembler (EXPERIMENTAL)

If you're using any Perl API calls, you need to pass a special variable to your assembler function: pTHX. This is actually a macro in C land, magically passed to all API calls. For example, this harmless snippet of C code:


   return newSVpv("Hello, World!", 0);

is really doing this:


   return Perl_newSVpv(aTHX_ "Hello, World!", 0);

Depending on your setup, aTHX_ might be undefined, empty, or a PerlInterpreter structure. In the perl that ships with RedHat Linux 6.2, this becomes:


   return Perl_newSVpv("Hello, World!", 0);

aTHX_ is a C macro which, depending on your setup, defines either a Perl interpreter or nothing. On perl 5.005_03 on my RedHat 6.2 box, aTHX_ is resolved to ``''. With ActivePerl 623, aTHX_ resolves to some pthreads calls which get the currently running interpeter.

Your assembler code doesn't know anything about Perl, so the user-level API is not available. You need to explicitly call Perl_newSVpv, passing it a Perl interpreter if your Perl expects one.

You can test if Perl wants a parameter running this code:


   use Inline C => <<END;

   void foo(pTHX_ int a) {

      printf("This perl interpreter is defined: %p\n", aTHX);

      return Perl_newSViv(aTHX_ a);

   };

   END

If the code compiles, Perl has been configured to pass a PerlInterpreter using the macros aTHX and pTHX. If the code fails because the macros weren't defined, or because of a parse error on the printf line, then the Perl interpreter is kept in a global variable and the macros aren't required.

You can get Inline::ASM to pass the Perl parameter to your assembler function by asking for it like this:


   print "9 + 16 = ", add(9, 16), "\n";

   use Inline ASM => 'DATA',

              AS => 'as',

              PROTO => {add => 'SV*(pTHX,int,int)};

   __END__

   .text

   .globl    add

   .extern   Perl_newSViv

   add:      movl 4(%esp),%ebx

             movl 8(%esp),%eax

             addl 12(%esp),%eax

             pushl %eax

             pushl %ebx

             call Perl_newSViv

             leave

             ret

Note that if your Perl configuration doesn't define the pTHX macro, this will cause a compile error. So basically you can't write portable assembler extensions.

Of course, if you want a portable solution, use the Inline::C manpage.


Examples

Example #1 - Greetings

This example takes a string argument (a name) and prints a greeting. The function is called with a string, then a number. Perl forces the number to a string.


   greet('Ingy');

   greet(42);

   use Inline ASM => <<'END', PROTO => { greet => 'void(char*)'};

   .data

   gstr:   .string "Hello %s!\n"

   .text

   .globl  greet

   greet:  movl 4(%esp),%eax

           pushl %eax

           pushl $gstr

           call printf

           leave

           ret

   END


SEE ALSO

For general information about Inline see Inline.

For information on supported languages and platforms see the Inline::Support manpage.

For information on writing your own Inline Language Support Module, see Inline-API.

Inline's mailing list is inline@perl.org

To subscribe, send email to inline-subscribe@perl.org


WARNING

Do NOT use assembler to write Perl extensions! It's sick and wrong!


AUTHOR

Neil Watkiss <NEILW@cpan.org>


COPYRIGHT

Copyright (c) 2001, Neil Watkiss.

All Rights Reserved. This module is free software. It may be used, redistributed and/or modified under the same terms as Perl itself.

(see http://www.perl.com/perl/misc/Artistic.html)

Programminig
Wy
Wy
yW
Wy
Programming
Wy
Wy
Wy
Wy