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!

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.

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.

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 Inline::C for additional information.

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.

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

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.

NASM (Netwide Assembler)

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

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 Inline::C 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.

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.

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: