mirror of https://github.com/tLDP/LDP
3973 lines
126 KiB
Plaintext
3973 lines
126 KiB
Plaintext
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook V3.1//EN" [
|
|
|
|
<!ENTITY version "0.6g">
|
|
|
|
<!ENTITY s-intro "<link linkend=s-intro>Introduction</link>">
|
|
<!ENTITY s-doyou "<link linkend=s-doyou>Do you need assembly?</link>">
|
|
<!ENTITY s-assem "<link linkend=s-assem>Assemblers</link>">
|
|
<!ENTITY s-meta "<link linkend=s-meta>Metaprogramming</link>">
|
|
<!ENTITY s-call "<link linkend=s-call>Calling conventions</link>">
|
|
<!ENTITY s-quick "<link linkend=s-quick>Quick Start</link>">
|
|
<!ENTITY s-res "<link linkend=s-res>Resources</link>">
|
|
<!ENTITY s-faq "<link linkend=s-faq>FAQ</link>">
|
|
<!ENTITY s-list "<link linkend=s-res-list>linux-assembly mailing list</link>">
|
|
|
|
]>
|
|
|
|
<!-- $Id$ -->
|
|
|
|
<book>
|
|
<?html-filename Assembly-HOWTO.html>
|
|
|
|
<bookinfo>
|
|
<title>Linux Assembly HOWTO</title>
|
|
|
|
<authorgroup>
|
|
<author>
|
|
<firstname>Konstantin</firstname>
|
|
<surname>Boldyshev</surname>
|
|
<affiliation>
|
|
<orgname>
|
|
<ulink url="http://linuxassembly.org">
|
|
Linux Assembly<anchor id="konst"></ulink>
|
|
</orgname>
|
|
<address>
|
|
<email>konst@linuxassembly.org</email>
|
|
</address>
|
|
</affiliation>
|
|
</author>
|
|
<author>
|
|
<firstname>Francois-Rene</firstname>
|
|
<surname>Rideau</surname>
|
|
<affiliation>
|
|
<orgname>
|
|
<ulink url="http://tunes.org">
|
|
Tunes project<anchor id="fare"></ulink>
|
|
</orgname>
|
|
<address>
|
|
<email>fare@tunes.org</email>
|
|
</address>
|
|
</affiliation>
|
|
</author>
|
|
</authorgroup>
|
|
|
|
<copyright>
|
|
<year>1999-2006</year><holder>Konstantin Boldyshev</holder>
|
|
</copyright>
|
|
<copyright>
|
|
<year>1996-1999</year><holder>Francois-Rene Rideau</holder>
|
|
</copyright>
|
|
|
|
<legalnotice><para>
|
|
Permission is granted to copy, distribute and/or modify this document
|
|
under the terms of the GNU Free Documentation License, Version 1.1;
|
|
with no Invariant Sections, with no Front-Cover Texts, and no Back-Cover texts.
|
|
</para></legalnotice>
|
|
|
|
<releaseinfo>Version &version;</releaseinfo>
|
|
<edition>&version;</edition>
|
|
<pubdate role="cvs">$Date$</pubdate>
|
|
|
|
<abstract>
|
|
<para>
|
|
This is the Linux Assembly HOWTO, version &version;.
|
|
This document describes how to program in assembly language
|
|
using <emphasis>free</emphasis> programming tools,
|
|
focusing on development for or from the Linux Operating System,
|
|
mostly on IA-32 (i386) platform.
|
|
Included material may or may not be applicable
|
|
to other hardware and/or software platforms.
|
|
</para>
|
|
</abstract>
|
|
|
|
<keywordset>
|
|
<keyword>assembly</keyword>
|
|
<keyword>assembler</keyword>
|
|
<keyword>asm</keyword>
|
|
<keyword>inline</keyword>
|
|
<keyword>32-bit</keyword>
|
|
<keyword>IA-32</keyword>
|
|
<keyword>i386</keyword>
|
|
<keyword>x86</keyword>
|
|
<keyword>nasm</keyword>
|
|
<keyword>gas</keyword>
|
|
<keyword>as</keyword>
|
|
<keyword>as86</keyword>
|
|
<keyword>yasm</keyword>
|
|
<keyword>fasm</keyword>
|
|
<keyword>shasm</keyword>
|
|
<keyword>osimpa</keyword>
|
|
<keyword>OS</keyword>
|
|
<keyword>Linux</keyword>
|
|
<keyword>Unix</keyword>
|
|
<keyword>kernel</keyword>
|
|
<keyword>system</keyword>
|
|
<keyword>libc</keyword>
|
|
<keyword>glibc</keyword>
|
|
<keyword>system call</keyword>
|
|
<keyword>interrupt</keyword>
|
|
<keyword>small</keyword>
|
|
<keyword>fast</keyword>
|
|
<keyword>embedded</keyword>
|
|
<keyword>hardware</keyword>
|
|
<keyword>port</keyword>
|
|
<keyword>macroprocessor</keyword>
|
|
<keyword>metaprogramming</keyword>
|
|
<keyword>preprocessor</keyword>
|
|
</keywordset>
|
|
|
|
</bookinfo>
|
|
|
|
|
|
<!--
|
|
start
|
|
-->
|
|
|
|
|
|
<chapter id="s-intro" xreflabel="Introduction">
|
|
<?html-filename introduction.html>
|
|
<title>Introduction</title>
|
|
|
|
<note><para>
|
|
You can skip this chapter if you are familiar with HOWTOs,
|
|
or just hate to read all this assembly-unrelated crap.
|
|
</para></note>
|
|
|
|
<simplesect><title>Legal Blurb</title>
|
|
|
|
<para>
|
|
Permission is granted to copy, distribute and/or modify this document
|
|
under the terms of the GNU
|
|
<ulink url="http://www.gnu.org/copyleft/fdl.html">
|
|
Free Documentation License</ulink> Version 1.1;
|
|
with no Invariant Sections, with no Front-Cover Texts, and no Back-Cover texts.
|
|
A copy of the license is included in the <xref linkend="a-gfdl"> appendix.
|
|
</para>
|
|
|
|
<para>
|
|
The most recent official version of this document is available from the
|
|
<ulink url="http://linuxassembly.org/howto.html">Linux Assembly</ulink> and
|
|
<ulink url="http://tldp.org/docs.html">LDP</ulink> sites.
|
|
If you are reading a few-months-old copy,
|
|
consider checking the above URLs for a new version.
|
|
</para>
|
|
|
|
</simplesect>
|
|
|
|
<simplesect><title>Foreword</title>
|
|
|
|
<para>
|
|
This document aims answering questions of those
|
|
who program or want to program 32-bit x86 assembly using
|
|
<emphasis>free software</emphasis>,
|
|
particularly under the Linux operating system.
|
|
At many places Universal Resource Locators (<acronym>URL</acronym>) are given
|
|
for some software or documentation repository.
|
|
This document also points to other documents about
|
|
non-free, non-x86, or non-32-bit assemblers,
|
|
although this is not its primary goal.
|
|
Also note that there are FAQs and docs about programming
|
|
on your favorite platform (whatever it is), which you should consult
|
|
for platform-specific issues, not related directly to assembly programming.
|
|
</para>
|
|
|
|
<para>
|
|
Because the main interest of assembly programming is to build
|
|
the guts of operating systems, interpreters, compilers, and games,
|
|
where C compiler fails to provide the needed expressiveness
|
|
(performance is more and more seldom as issue),
|
|
we are focusing on development of such kind of software.
|
|
</para>
|
|
|
|
<para>
|
|
If you don't know what
|
|
<ulink url="http://www.gnu.org/philosophy/">
|
|
<emphasis>free software</emphasis></ulink> is,
|
|
please do read <emphasis>carefully</emphasis>
|
|
the GNU <ulink url="http://www.gnu.org/copyleft/gpl.html">
|
|
General Public License</ulink>
|
|
(<acronym>GPL</acronym> or <acronym>copyleft</acronym>),
|
|
which is used in a lot of free software,
|
|
and is the model for most of their licenses.
|
|
It generally comes in a file named <filename>COPYING</filename>
|
|
(or <filename>COPYING.LIB</filename>).
|
|
Literature from the
|
|
<ulink url="http://www.fsf.org">Free Software Foundation</ulink>
|
|
(<acronym>FSF</acronym>) might help you too.
|
|
Particularly, the interesting feature of free software
|
|
is that it comes with source code which you can consult and correct,
|
|
or sometimes even borrow from.
|
|
Read your particular license carefully and do comply to it.
|
|
</para>
|
|
|
|
</simplesect>
|
|
|
|
<simplesect><title>Contributions</title>
|
|
|
|
<para>
|
|
This is an interactively evolving document: you are especially invited
|
|
to ask questions,
|
|
to answer questions,
|
|
to correct given answers,
|
|
to give pointers to new software,
|
|
to point the current maintainer to bugs or deficiencies in the pages.
|
|
In one word, contribute!
|
|
</para>
|
|
|
|
<para>
|
|
To contribute, please contact the <link linkend="konst">maintainer</link>.
|
|
</para>
|
|
|
|
<note><para>
|
|
At the time of writing, it is
|
|
<link linkend="konst">Konstantin Boldyshev</link>
|
|
and no more
|
|
<link linkend="fare">Francois-Rene Rideau</link> (since version 0.5).
|
|
I (<link linkend="fare">Fare</link>) had been looking for some time
|
|
for a serious hacker to replace me as maintainer of this document,
|
|
and am pleased to announce
|
|
<link linkend="konst">Konstantin</link> as my worthy successor.
|
|
</para></note>
|
|
|
|
</simplesect>
|
|
|
|
<simplesect><title>Translations</title>
|
|
|
|
<para>
|
|
Korean translation of this HOWTO is avalilable at
|
|
<ulink url="http://kldp.org/HOWTO/html/Assembly-HOWTO/">
|
|
http://kldp.org/HOWTO/html/Assembly-HOWTO/</ulink>.
|
|
Turkish translation of this HOWTO is available at
|
|
<ulink url="http://belgeler.org/howto/assembly-howto.html">
|
|
http://belgeler.org/howto/assembly-howto.html</ulink>.
|
|
Incomplete Russian translation is available at
|
|
<ulink url="http://volgograd.lug.ru/wiki/GrableVodstvo/articles/AssembleInLinux/">
|
|
http://volgograd.lug.ru/wiki/GrableVodstvo/articles/AssembleInLinux/</ulink>.
|
|
Also, there was a French translation of the early HOWTO versions,
|
|
but I can't find it now.
|
|
</para>
|
|
|
|
</simplesect>
|
|
|
|
</chapter>
|
|
|
|
<chapter id="s-doyou" xreflabel="Do you need assembly?">
|
|
<?html-filename doyouneed.html>
|
|
<title>Do you need assembly?</title>
|
|
|
|
<para>
|
|
Well, I wouldn't want to interfere with what you're doing,
|
|
but here is some advice from the hard-earned experience.
|
|
</para>
|
|
|
|
<section><title>Pros and Cons</title>
|
|
|
|
<section><title>The advantages of Assembly</title>
|
|
|
|
<para>
|
|
Assembly can express very low-level things:
|
|
|
|
<itemizedlist>
|
|
<listitem><para>
|
|
you can access machine-dependent registers and I/O
|
|
</para></listitem>
|
|
<listitem><para>
|
|
you can control the exact code behavior
|
|
in critical sections that might otherwise involve deadlock
|
|
between multiple software threads or hardware devices
|
|
</para></listitem>
|
|
<listitem><para>
|
|
you can break the conventions of your usual compiler,
|
|
which might allow some optimizations
|
|
(like temporarily breaking rules about memory allocation,
|
|
threading, calling conventions, etc)
|
|
</para></listitem>
|
|
<listitem><para>
|
|
you can build interfaces between code fragments
|
|
using incompatible conventions
|
|
(e.g. produced by different compilers,
|
|
or separated by a low-level interface)
|
|
</para></listitem>
|
|
<listitem><para>
|
|
you can get access to unusual programming modes of your processor
|
|
(e.g. 16 bit mode to interface startup, firmware, or legacy code
|
|
on Intel PCs)
|
|
</para></listitem>
|
|
<listitem><para>
|
|
you can produce reasonably fast code for tight loops
|
|
to cope with a bad non-optimizing compiler
|
|
(but then, there are free optimizing compilers available!)
|
|
</para></listitem>
|
|
<listitem><para>
|
|
you can produce hand-optimized code
|
|
perfectly tuned for your particular hardware setup,
|
|
though not to someone else's
|
|
</para></listitem>
|
|
<listitem><para>
|
|
you can write some code for your new language's optimizing compiler
|
|
(that is something what very few ones will ever do, and even they not often)
|
|
</para></listitem>
|
|
<listitem><para>
|
|
i.e. you can be in complete control of your code
|
|
</para></listitem>
|
|
</itemizedlist>
|
|
|
|
</para>
|
|
|
|
</section>
|
|
|
|
<section><title>The disadvantages of Assembly</title>
|
|
|
|
<para>
|
|
Assembly is a very low-level language
|
|
(the lowest above hand-coding the binary instruction patterns).
|
|
This means
|
|
|
|
<itemizedlist>
|
|
<listitem><para>
|
|
it is long and tedious to write initially
|
|
</para></listitem>
|
|
<listitem><para>
|
|
it is quite bug-prone
|
|
</para></listitem>
|
|
<listitem><para>
|
|
your bugs can be very difficult to chase
|
|
</para></listitem>
|
|
<listitem><para>
|
|
your code can be fairly difficult to understand and modify,
|
|
i.e. to maintain
|
|
</para></listitem>
|
|
<listitem><para>
|
|
the result is non-portable to other architectures,
|
|
existing or upcoming
|
|
</para></listitem>
|
|
<listitem><para>
|
|
your code will be optimized only for a certain implementation
|
|
of a same architecture:
|
|
for instance, among Intel-compatible platforms
|
|
each CPU design and its variations
|
|
(relative latency, through-output, and capacity,
|
|
of processing units, caches, RAM, bus, disks,
|
|
presence of FPU, MMX, 3DNOW, SIMD extensions, etc)
|
|
implies potentially completely different optimization techniques.
|
|
CPU designs already include:
|
|
Intel 386, 486, Pentium, PPro, PII, PIII, PIV;
|
|
Cyrix 5x86, 6x86, M2; AMD K5, K6 (K6-2, K6-III), K7 (Athlon, Duron).
|
|
New designs keep popping up, so don't expect either this listing
|
|
and your code to be up-to-date.
|
|
</para></listitem>
|
|
<listitem><para>
|
|
you spend more time on a few details
|
|
and can't focus on small and large algorithmic design,
|
|
that are known to bring the largest part of the speed up
|
|
(e.g. you might spend some time building very fast
|
|
list/array manipulation primitives in assembly;
|
|
only a hash table would have sped up your program much more;
|
|
or, in another context, a binary tree;
|
|
or some high-level structure distributed over a cluster of CPUs)
|
|
</para></listitem>
|
|
<listitem><para>
|
|
a small change in algorithmic design might completely
|
|
invalidate all your existing assembly code.
|
|
So that either you're ready (and able) to rewrite it all,
|
|
or you're tied to a particular algorithmic design
|
|
</para></listitem>
|
|
<listitem><para>
|
|
On code that ain't too far from what's in standard benchmarks,
|
|
commercial optimizing compilers outperform hand-coded assembly
|
|
(well, that's less true on the x86 architecture than on RISC architectures,
|
|
and perhaps less true for widely available/free compilers;
|
|
anyway, for typical C code, GCC is fairly good);
|
|
</para></listitem>
|
|
<listitem><para>
|
|
And in any case, as moderator John Levine says on
|
|
<ulink url="news:comp.compilers">comp.compilers</ulink>,
|
|
</para>
|
|
<literallayout>
|
|
"compilers make it a lot easier to use complex data structures,
|
|
and compilers don't get bored halfway through
|
|
and generate reliably pretty good code."
|
|
</literallayout>
|
|
<para>
|
|
They will also <emphasis>correctly</emphasis> propagate code transformations
|
|
throughout the whole (huge) program
|
|
when optimizing code between procedures and module boundaries.
|
|
</para></listitem>
|
|
</itemizedlist>
|
|
|
|
</para>
|
|
|
|
</section>
|
|
|
|
<section><title>Assessment</title>
|
|
|
|
<para>
|
|
All in all, you might find that though using assembly is sometimes needed,
|
|
and might even be useful in a few cases where it is not, you'll want to:
|
|
|
|
<itemizedlist>
|
|
<listitem><para>
|
|
minimize use of assembly code
|
|
</para></listitem>
|
|
<listitem><para>
|
|
encapsulate this code in well-defined interfaces
|
|
</para></listitem>
|
|
<listitem><para>
|
|
have your assembly code automatically generated
|
|
from patterns expressed in a higher-level language
|
|
than assembly (e.g. GCC inline assembly macros)
|
|
</para></listitem>
|
|
<listitem><para>
|
|
have automatic tools translate these programs
|
|
into assembly code
|
|
</para></listitem>
|
|
<listitem><para>
|
|
have this code be optimized if possible
|
|
</para></listitem>
|
|
<listitem><para>
|
|
All of the above,
|
|
i.e. write (an extension to) an optimizing compiler back-end.
|
|
</para></listitem>
|
|
</itemizedlist>
|
|
|
|
</para>
|
|
|
|
<para>
|
|
Even when assembly is needed (e.g. OS development),
|
|
you'll find that not so much of it is required,
|
|
and that the above principles retain.
|
|
</para>
|
|
|
|
<para>
|
|
See the Linux kernel sources concerning this:
|
|
as little assembly as needed,
|
|
resulting in a fast, reliable, portable, maintainable OS.
|
|
Even a successful game like DOOM was almost massively written in C,
|
|
with a tiny part only being written in assembly for speed up.
|
|
</para>
|
|
|
|
</section>
|
|
|
|
</section>
|
|
|
|
<section>
|
|
<?html-filename howtonot.html>
|
|
<title>How to NOT use Assembly</title>
|
|
|
|
<section><title>General procedure to achieve efficient code</title>
|
|
|
|
<para>
|
|
As Charles Fiterman says on
|
|
<ulink url="news:comp.compilers">comp.compilers</ulink>
|
|
about human vs computer-generated assembly code:
|
|
</para>
|
|
|
|
<blockquote>
|
|
<literallayout>
|
|
The human should always win and here is why.
|
|
|
|
First the human writes the whole thing in a high level language.
|
|
Second he profiles it to find the hot spots where it spends its time.
|
|
Third he has the compiler produce assembly for those small sections of code.
|
|
Fourth he hand tunes them looking for tiny improvements over the machine generated code.
|
|
|
|
The human wins because he can use the machine.
|
|
</literallayout></blockquote>
|
|
|
|
</section>
|
|
|
|
<section><title>Languages with optimizing compilers</title>
|
|
|
|
<para>
|
|
Languages like ObjectiveCAML, SML, CommonLISP, Scheme, ADA, Pascal, C, C++,
|
|
among others, all have free optimizing compilers
|
|
that will optimize the bulk of your programs,
|
|
and often do better than hand-coded assembly even for tight loops,
|
|
while allowing you to focus on higher-level details,
|
|
and without forbidding you to grab
|
|
a few percent of extra performance in the above-mentioned way,
|
|
once you've reached a stable design.
|
|
Of course, there are also commercial optimizing compilers
|
|
for most of these languages, too!
|
|
</para>
|
|
|
|
<para>
|
|
Some languages have compilers that produce C code,
|
|
which can be further optimized by a C compiler:
|
|
LISP, Scheme, Perl, and many other.
|
|
Speed is fairly good.
|
|
</para>
|
|
|
|
</section>
|
|
|
|
<section><title>General procedure to speed your code up</title>
|
|
|
|
<para>
|
|
As for speeding code up,
|
|
you should do it only for parts of a program
|
|
that a profiling tool has consistently identified
|
|
as being a performance bottleneck.
|
|
</para>
|
|
|
|
<para>
|
|
Hence, if you identify some code portion as being too slow, you should
|
|
|
|
<itemizedlist>
|
|
<listitem><para>
|
|
first try to use a better algorithm;
|
|
</para></listitem>
|
|
<listitem><para>
|
|
then try to compile it rather than interpret it;
|
|
</para></listitem>
|
|
<listitem><para>
|
|
then try to enable and tweak optimization from your compiler;
|
|
</para></listitem>
|
|
<listitem><para>
|
|
then give the compiler hints about how to optimize
|
|
(typing information in LISP; register usage with GCC;
|
|
lots of options in most compilers, etc).
|
|
</para></listitem>
|
|
<listitem><para>
|
|
then possibly fallback to assembly programming
|
|
</para></listitem>
|
|
</itemizedlist>
|
|
|
|
</para>
|
|
|
|
<para>
|
|
Finally, before you end up writing assembly,
|
|
you should inspect generated code,
|
|
to check that the problem really is with bad code generation,
|
|
as this might really not be the case:
|
|
compiler-generated code might be better than what you'd have written,
|
|
particularly on modern multi-pipelined architectures!
|
|
Slow parts of a program might be intrinsically so.
|
|
The biggest problems on modern architectures with fast processors
|
|
are due to delays from memory access, cache-misses, TLB-misses,
|
|
and page-faults;
|
|
register optimization becomes useless,
|
|
and you'll more profitably re-think data structures and threading
|
|
to achieve better locality in memory access.
|
|
Perhaps a completely different approach to the problem might help, then.
|
|
</para>
|
|
|
|
</section>
|
|
|
|
<section><title>Inspecting compiler-generated code</title>
|
|
|
|
<para>
|
|
There are many reasons to inspect compiler-generated assembly code.
|
|
Here is what you'll do with such code:
|
|
|
|
<itemizedlist>
|
|
<listitem><para>
|
|
check whether generated code
|
|
can be obviously enhanced with hand-coded assembly
|
|
(or by tweaking compiler switches)
|
|
</para></listitem>
|
|
<listitem><para>
|
|
when that's the case,
|
|
start from generated code and modify it
|
|
instead of starting from scratch
|
|
</para></listitem>
|
|
<listitem><para>
|
|
more generally, use generated code as stubs to modify,
|
|
which at least gets right the way
|
|
your assembly routines interface to the external world
|
|
</para></listitem>
|
|
<listitem><para>
|
|
track down bugs in your compiler (hopefully the rarer)
|
|
</para></listitem>
|
|
</itemizedlist>
|
|
|
|
</para>
|
|
|
|
<para>
|
|
The standard way to have assembly code be generated
|
|
is to invoke your compiler with the <option>-S</option> flag.
|
|
This works with most Unix compilers,
|
|
including the GNU C Compiler (GCC), but YMMV.
|
|
As for GCC, it will produce more understandable assembly code with
|
|
the <option>-fverbose-asm</option> command-line option.
|
|
Of course, if you want to get good assembly code,
|
|
don't forget your usual optimization options and hints!
|
|
</para>
|
|
|
|
</section>
|
|
|
|
</section>
|
|
|
|
<section>
|
|
<?html-filename landa.html>
|
|
<title>Linux and assembly</title>
|
|
|
|
<para>
|
|
As you probably noticed, in general case
|
|
you don't need to use assembly language in Linux programming.
|
|
Unlike DOS, you do not have to write Linux drivers in assembly
|
|
(well, actually you can do it if you really want).
|
|
And with modern optimizing compilers,
|
|
if you care of speed optimization for different CPU's,
|
|
it's much simpler to write in C.
|
|
However, if you're reading this,
|
|
you might have some reason to use assembly instead of C/C++.
|
|
</para>
|
|
|
|
<para>
|
|
You may <emphasis>need</emphasis> to use assembly, or you may <emphasis>want</emphasis> to use assembly.
|
|
In short, main practical (<emphasis>need</emphasis>) reasons
|
|
of diving into the assembly realm are <emphasis>small code</emphasis>
|
|
and <emphasis><application>libc</application> independence</emphasis>.
|
|
Impractical (<emphasis>want</emphasis>), and the most often reason is
|
|
being just an old crazy hacker,
|
|
who has twenty years old habit of doing everything in assembly language.
|
|
</para>
|
|
|
|
<para>
|
|
However, if you're porting Linux to some embedded hardware
|
|
you can be quite short at the size of whole system:
|
|
you need to fit kernel, <application>libc</application>
|
|
and all that stuff of <application>(file|find|text|sh|etc.) utils</application>
|
|
into several hundreds of kilobytes,
|
|
and every kilobyte costs much.
|
|
So, one of the possible ways is to rewrite some
|
|
(or all) parts of system in assembly,
|
|
and this will really save you a lot of space.
|
|
For instance, a simple <command>httpd</command> written in assembly
|
|
can take less than 600 bytes;
|
|
you can fit a server consisting of kernel, httpd and ftpd
|
|
in 400 KB or less... Think about it.
|
|
</para>
|
|
|
|
</section>
|
|
|
|
</chapter>
|
|
|
|
<chapter id="s-assem" xreflabel="Assemblers">
|
|
<?html-filename assemblers.html>
|
|
<title>Assemblers</title>
|
|
|
|
<section id="p-gcc">
|
|
<?html-filename gcc.html>
|
|
<title>GCC Inline Assembly</title>
|
|
|
|
<para>
|
|
The well-known GNU C/C++ Compiler (GCC),
|
|
an optimizing 32-bit compiler at the heart of the GNU project,
|
|
supports the x86 architecture quite well,
|
|
and includes the ability to insert assembly code in C programs,
|
|
in such a way that register allocation can be either specified or left to GCC.
|
|
GCC works on most available platforms,
|
|
notably Linux, *BSD, VSTa, OS/2, *DOS, Win*, etc.
|
|
</para>
|
|
|
|
<section><title>Where to find GCC</title>
|
|
|
|
<para>
|
|
GCC home page is <ulink url="http://gcc.gnu.org">
|
|
http://gcc.gnu.org</ulink>.
|
|
</para>
|
|
|
|
<para>
|
|
<anchor id="p-djgpp">
|
|
DOS port of GCC is called
|
|
<ulink url="http://www.delorie.com/djgpp/">DJGPP</ulink>.
|
|
</para>
|
|
|
|
<para>
|
|
There are two Win32 GCC ports:
|
|
<ulink url="http://www.cygwin.com">cygwin</ulink> and
|
|
<ulink url="http://www.mingw.org">mingw</ulink>
|
|
</para>
|
|
|
|
<para>
|
|
There is also an OS/2 port of GCC called EMX;
|
|
it works under DOS too,
|
|
and includes lots of unix-emulation library routines.
|
|
Look around the following site:
|
|
<ulink url="ftp://ftp.leo.org/pub/comp/os/os2/leo/gnu/emx+gcc/">
|
|
ftp://ftp.leo.org/pub/comp/os/os2/leo/gnu/emx+gcc/
|
|
</ulink>.
|
|
</para>
|
|
|
|
</section>
|
|
|
|
<section><title>Where to find docs for GCC Inline Asm</title>
|
|
|
|
<para>
|
|
The documentation of GCC includes documentation files in TeXinfo format.
|
|
You can compile them with TeX and print then result,
|
|
or convert them to <filename>.info</filename>, and browse them with emacs,
|
|
or convert them to <filename>.html</filename>, or nearly whatever you like;
|
|
convert (with the right tools) to whatever you like,
|
|
or just read as is. The <filename>.info</filename> files
|
|
are generally found on any good installation for GCC.
|
|
</para>
|
|
|
|
<para>
|
|
The right section to look for is <literal>C Extensions::Extended Asm::</literal>
|
|
</para>
|
|
|
|
<para>
|
|
Section <literal>Invoking GCC::Submodel Options::i386 Options::</literal> might help too.
|
|
Particularly, it gives the i386 specific constraint names for registers:
|
|
<literal>abcdSDB</literal> correspond to
|
|
<literal>%eax</literal>,
|
|
<literal>%ebx</literal>,
|
|
<literal>%ecx</literal>,
|
|
<literal>%edx</literal>,
|
|
<literal>%esi</literal>,
|
|
<literal>%edi</literal>
|
|
and
|
|
<literal>%ebp</literal>
|
|
respectively (no letter for <literal>%esp</literal>).
|
|
</para>
|
|
|
|
<para>
|
|
The DJGPP Games resource (not only for game hackers) had page
|
|
specifically about assembly, but it's down.
|
|
Its data have nonetheless been recovered on the
|
|
<link linkend="p-djgpp">DJGPP site</link>,
|
|
that contains a mine of other useful information:
|
|
<ulink url="http://www.delorie.com/djgpp/doc/brennan/">
|
|
http://www.delorie.com/djgpp/doc/brennan/</ulink>.
|
|
</para>
|
|
|
|
<para>
|
|
GCC depends on GAS for assembling and follows its syntax (see below);
|
|
do mind that inline asm needs percent characters to be quoted,
|
|
they will be passed to GAS.
|
|
See the section about GAS below.
|
|
</para>
|
|
|
|
<para>
|
|
Find <emphasis>lots</emphasis> of useful examples in the
|
|
<filename>linux/include/asm-i386/</filename>
|
|
subdirectory of the sources for the Linux kernel.
|
|
</para>
|
|
|
|
</section>
|
|
|
|
<section><title>Invoking GCC to build proper inline assembly code</title>
|
|
|
|
<para>
|
|
Because assembly routines from the kernel headers
|
|
(and most likely your own headers,
|
|
if you try making your assembly programming as clean
|
|
as it is in the linux kernel)
|
|
are embedded in <function>extern inline</function> functions,
|
|
GCC must be invoked with the <option>-O</option> flag
|
|
(or <option>-O2</option>, <option>-O3</option>, etc),
|
|
for these routines to be available.
|
|
If not, your code may compile, but not link properly,
|
|
since it will be looking for non-inlined <function>extern</function> functions
|
|
in the libraries against which your program is being linked!
|
|
Another way is to link against libraries that include fallback
|
|
versions of the routines.
|
|
</para>
|
|
|
|
<para>
|
|
Inline assembly can be disabled with <option>-fno-asm</option>,
|
|
which will have the compiler die when using extended inline asm syntax,
|
|
or else generate calls to an external function named <function>asm()</function>
|
|
that the linker can't resolve.
|
|
To counter such flag, <option>-fasm</option> restores treatment
|
|
of the <literal>asm</literal> keyword.
|
|
</para>
|
|
|
|
<para>
|
|
More generally, good compile flags for GCC on the x86 platform are
|
|
</para>
|
|
|
|
<para>
|
|
<command>gcc -O2 -fomit-frame-pointer -W -Wall</command>
|
|
</para>
|
|
|
|
<para>
|
|
<option>-O2</option> is the good optimization level in most cases.
|
|
Optimizing besides it takes more time, and yields code that is much larger,
|
|
but only a bit faster;
|
|
such over-optimization might be useful for tight loops only (if any),
|
|
which you may be doing in assembly anyway.
|
|
In cases when you need really strong compiler optimization for a few files,
|
|
do consider using up to <option>-O6</option>.
|
|
</para>
|
|
|
|
<para>
|
|
<option>-fomit-frame-pointer</option> allows generated code to skip
|
|
the stupid frame pointer maintenance, which makes code smaller and faster,
|
|
and frees a register for further optimizations.
|
|
It precludes the easy use of debugging tools (<command>gdb</command>),
|
|
but when you use these, you just don't care about size and speed anymore anyway.
|
|
</para>
|
|
|
|
<para>
|
|
<option>-W -Wall</option> enables all useful warnings
|
|
and helps you to catch obvious stupid errors.
|
|
</para>
|
|
|
|
<para>
|
|
You can add some CPU-specific <option>-m486</option> or such flag so that
|
|
GCC will produce code that is more adapted to your precise CPU.
|
|
Note that modern GCC has <option>-mpentium</option> and such flags
|
|
(and <ulink url="http://goof.com/pcg/">PGCC</ulink> has even more),
|
|
whereas GCC 2.7.x and older versions do not.
|
|
A good choice of CPU-specific flags should be in the Linux kernel.
|
|
Check the TeXinfo documentation of your current GCC installation for more.
|
|
</para>
|
|
|
|
<para>
|
|
<option>-m386</option> will help optimize for size,
|
|
hence also for speed on computers whose memory is tight and/or loaded,
|
|
since big programs cause swap, which more than counters
|
|
any "optimization" intended by the larger code.
|
|
In such settings, it might be useful to stop using C,
|
|
and use instead a language that favors code factorization,
|
|
such as a functional language and/or FORTH,
|
|
and use a bytecode- or wordcode- based implementation.
|
|
</para>
|
|
|
|
<para>
|
|
Note that you can vary code generation flags from file to file,
|
|
so performance-critical files will use maximum optimization,
|
|
whereas other files will be optimized for size.
|
|
</para>
|
|
|
|
<para>
|
|
To optimize even more, option <option>-mregparm=2</option>
|
|
and/or corresponding function attribute might help,
|
|
but might pose lots of problems when linking to foreign code,
|
|
<emphasis>including <application>libc</application></emphasis>.
|
|
There are ways to correctly declare foreign functions
|
|
so the right call sequences be generated,
|
|
or you might want to recompile the foreign libraries
|
|
to use the same register-based calling convention...
|
|
</para>
|
|
|
|
<para>
|
|
Note that you can add make these flags the default by editing file
|
|
<filename>/usr/lib/gcc-lib/i486-linux/2.7.2.3/specs</filename>
|
|
or wherever that is on your system
|
|
(better not add <option>-W -Wall</option> there, though).
|
|
The exact location of the GCC specs files on system can be found by
|
|
<command>gcc -v</command>.
|
|
</para>
|
|
|
|
</section>
|
|
|
|
<section><title>Macro support</title>
|
|
|
|
<para>
|
|
GCC allows (and requires) you to specify register constraints
|
|
in your inline assembly code, so the optimizer always know about it;
|
|
thus, inline assembly code is really made of patterns,
|
|
not forcibly exact code.
|
|
</para>
|
|
|
|
<para>
|
|
Thus, you can put your assembly into CPP macros, and inline C functions,
|
|
so anyone can use it in as any C function/macro.
|
|
Inline functions resemble macros very much, but are sometimes cleaner to use.
|
|
Beware that in all those cases, code will be duplicated,
|
|
so only local labels (of <literal>1:</literal> style)
|
|
should be defined in that asm code.
|
|
However, a macro would allow the name for a non local defined label
|
|
to be passed as a parameter
|
|
(or else, you should use additional meta-programming methods).
|
|
Also, note that propagating inline asm code will spread potential bugs in them;
|
|
so watch out doubly for register constraints in such inline asm code.
|
|
</para>
|
|
|
|
<para>
|
|
Lastly, the C language itself may be considered as a good abstraction
|
|
to assembly programming,
|
|
which relieves you from most of the trouble of assembling.
|
|
</para>
|
|
|
|
</section>
|
|
|
|
|
|
</section>
|
|
|
|
<section id="p-gas" xreflabel="GAS">
|
|
<?html-filename gas.html>
|
|
<title>GAS</title>
|
|
|
|
<para>
|
|
GAS is the GNU Assembler, that GCC relies upon.
|
|
</para>
|
|
|
|
<section><title>Where to find it</title>
|
|
|
|
<para>
|
|
Find it at the same place where you've found GCC,
|
|
in the binutils package.
|
|
The latest version of binutils is available from
|
|
<ulink url="http://sources.redhat.com/binutils/">
|
|
http://sources.redhat.com/binutils/
|
|
</ulink>.
|
|
</para>
|
|
|
|
</section>
|
|
|
|
<section><title>What is this AT&T syntax</title>
|
|
|
|
<para>
|
|
Because GAS was invented to support a 32-bit unix compiler,
|
|
it uses standard AT&T syntax,
|
|
which resembles a lot the syntax for standard m68k assemblers,
|
|
and is standard in the UNIX world.
|
|
This syntax is neither worse, nor better than the Intel syntax.
|
|
It's just different.
|
|
When you get used to it,
|
|
you find it much more regular than the Intel syntax,
|
|
though a bit boring.
|
|
</para>
|
|
|
|
<para>
|
|
Here are the major caveats about GAS syntax:
|
|
|
|
<itemizedlist>
|
|
<listitem><para>
|
|
Register names are prefixed with <literal>%</literal>, so that registers
|
|
are <literal>%eax</literal>, <literal>%dl</literal> and so on,
|
|
instead of just <literal>eax</literal>, <literal>dl</literal>, etc.
|
|
This makes it possible to include external C symbols directly
|
|
in assembly source, without any risk of confusion, or any need
|
|
for ugly underscore prefixes.
|
|
</para></listitem>
|
|
<listitem><para>
|
|
The order of operands is source(s) first, and destination last,
|
|
as opposed to the Intel convention of destination first and sources last.
|
|
Hence, what in Intel syntax is
|
|
<function>mov eax,edx</function>
|
|
(move contents of register <literal>edx</literal> into register <literal>eax</literal>)
|
|
will be in GAS syntax
|
|
<function>mov %edx,%eax</function>.
|
|
</para></listitem>
|
|
<listitem><para>
|
|
The operand size is specified as a suffix to the instruction name.
|
|
The suffix is
|
|
<literal>b</literal> for (8-bit) byte,
|
|
<literal>w</literal> for (16-bit) word, and
|
|
<literal>l</literal> for (32-bit) long.
|
|
For instance, the correct syntax for the above instruction
|
|
would have been <function>movl %edx,%eax</function>.
|
|
However, gas does not require strict AT&T syntax,
|
|
so the suffix is optional when size can be guessed from register operands,
|
|
and else defaults to 32-bit (with a warning).
|
|
</para></listitem>
|
|
<listitem><para>
|
|
Immediate operands are marked with a <literal>$</literal> prefix,
|
|
as in <function>addl $5,%eax</function>
|
|
(add immediate long value 5 to register <literal>%eax</literal>).
|
|
</para></listitem>
|
|
<listitem><para>
|
|
Missing operand prefix indicates that it is memory-contents;
|
|
hence <function>movl $foo,%eax</function>
|
|
puts the <emphasis>address</emphasis> of variable <literal>foo</literal>
|
|
into register <literal>%eax</literal>,
|
|
but <function>movl foo,%eax</function>
|
|
puts the <emphasis>contents</emphasis> of variable <literal>foo</literal>
|
|
into register <literal>%eax</literal>.
|
|
</para></listitem>
|
|
<listitem><para>
|
|
Indexing or indirection is done by enclosing the index register
|
|
or indirection memory cell address in parentheses,
|
|
as in <function>testb $0x80,17(%ebp)</function>
|
|
(test the high bit of the byte value at offset 17
|
|
from the cell pointed to by <literal>%ebp</literal>).
|
|
</para></listitem>
|
|
</itemizedlist>
|
|
|
|
</para>
|
|
|
|
<para>
|
|
<anchor id="p-convert">
|
|
Note: There are <link linkend="s-res">few programs</link> which may help you
|
|
to convert source code between AT&T and Intel assembler syntaxes;
|
|
some of the are capable of performing conversion in both directions.
|
|
</para>
|
|
|
|
<para>
|
|
GAS has comprehensive documentation in TeXinfo format,
|
|
which comes at least with the source distribution.
|
|
Browse extracted <filename>.info</filename> pages with Emacs or whatever.
|
|
There used to be a file named gas.doc or as.doc
|
|
around the GAS source package, but it was merged into the TeXinfo docs.
|
|
Of course, in case of doubt, the ultimate documentation
|
|
is the sources themselves!
|
|
A section that will particularly interest you is
|
|
<literal>Machine Dependencies::i386-Dependent::</literal>
|
|
</para>
|
|
|
|
<para>
|
|
Again, the sources for Linux (the OS kernel) come in as excellent examples;
|
|
see under <filename>linux/arch/i386/</filename> the following files:
|
|
<filename>kernel/*.S</filename>,
|
|
<filename>boot/compressed/*.S</filename>,
|
|
<filename>math-emu/*.S</filename>.
|
|
</para>
|
|
|
|
<para>
|
|
If you are writing kind of a language, a thread package, etc.,
|
|
you might as well see how other languages (
|
|
<ulink url="http://para.inria.fr/">OCaml</ulink>,
|
|
<ulink url="http://www.jwdt.com/~paysan/gforth.html">Gforth</ulink>,
|
|
etc.),
|
|
or thread packages (QuickThreads, MIT pthreads, LinuxThreads, etc),
|
|
or whatever else do it.
|
|
</para>
|
|
|
|
<para>
|
|
Finally, just compiling a C program to assembly
|
|
might show you the syntax for the kind of instructions you want.
|
|
See section <xref linkend="s-doyou"> above.
|
|
</para>
|
|
|
|
</section>
|
|
|
|
<section><title>Intel syntax</Title>
|
|
|
|
<para>
|
|
Good news are that starting from binutils 2.10 release,
|
|
GAS supports Intel syntax too.
|
|
It can be triggered with <literal>.intel_syntax</literal> directive.
|
|
Unfortunately this mode is not documented (yet?) in the official
|
|
binutils manual, so if you want to use it, try to examine
|
|
<ulink url="http://www.lxhp.in-berlin.de/lhpas86.html">
|
|
http://www.lxhp.in-berlin.de/lhpas86.html</ulink>,
|
|
which is an extract from AMD 64bit port of binutils 2.11.
|
|
</para>
|
|
|
|
</section>
|
|
|
|
<section><title>16-bit mode</title>
|
|
|
|
<para>
|
|
Binutils (2.9.1.0.25+) now fully support 16-bit mode
|
|
(registers <emphasis>and</emphasis> addressing) on i386 PCs.
|
|
Use <literal>.code16</literal> and <literal>.code32</literal>
|
|
to switch between assembly modes.
|
|
</para>
|
|
|
|
<para>
|
|
Also, a neat trick used by several people (including the oskit authors)
|
|
is to force GCC to produce code for 16-bit real mode,
|
|
using an inline assembly statement
|
|
<literal>asm(".code16\n")</literal>.
|
|
GCC will still emit only 32-bit addressing modes,
|
|
but GAS will insert proper 32-bit prefixes for them.
|
|
</para>
|
|
|
|
</section>
|
|
|
|
<section><title>Macro support</title>
|
|
<para>
|
|
GAS has some macro capability included, as detailed in the texinfo docs.
|
|
Moreover, while GCC recognizes <filename>.s</filename> files as raw assembly
|
|
to send to GAS, it also recognizes <filename>.S</filename> files as files
|
|
to pipe through CPP before feeding them to GAS.
|
|
Again and again, see Linux sources for examples.
|
|
</para>
|
|
|
|
<para>
|
|
GAS also has GASP (GAS Preprocessor),
|
|
which adds all the usual macroassembly tricks to GAS.
|
|
GASP comes together with GAS in the GNU binutils archive.
|
|
It works as a filter, like <xref linkend="p-cpp"> and <xref linkend="p-m4">.
|
|
I have no idea on details, but it comes with its own texinfo documentation,
|
|
which you would like to browse (<command>info gasp</command>), print, grok.
|
|
GAS with GASP looks like a regular macro-assembler to me.
|
|
</para>
|
|
|
|
</section>
|
|
|
|
</section>
|
|
|
|
<section id="p-nasm" xreflabel="NASM">
|
|
<?html-filename nasm.html>
|
|
<title>NASM</title>
|
|
|
|
<para>
|
|
The Netwide Assembler project provides cool i386 assembler,
|
|
written in C, that should be modular enough
|
|
to eventually support all known syntaxes and object formats.
|
|
</para>
|
|
|
|
<section id="p-nasm-where">
|
|
<title>Where to find NASM</title>
|
|
|
|
<para>
|
|
<ulink url="http://nasm.sourceforge.net">http://nasm.sourceforge.net</ulink>,
|
|
<ulink url="http://sourceforge.net/projects/nasm/">http://sourceforge.net/projects/nasm/</ulink>
|
|
|
|
</para>
|
|
|
|
<para>
|
|
Binary release on your usual metalab mirror
|
|
in <filename>devel/lang/asm/</filename> directory.
|
|
Should also be available as <filename>.rpm</filename> or
|
|
<filename>.deb</filename> in your usual Linux distribution.
|
|
</para>
|
|
|
|
</section>
|
|
|
|
<section><title>What it does</title>
|
|
|
|
<para>
|
|
The syntax is Intel-style.
|
|
Comprehensive macroprocessing support is integrated.
|
|
</para>
|
|
|
|
<para>
|
|
Supported object file formats are
|
|
<literal>bin</literal>,
|
|
<literal>aout</literal>,
|
|
<literal>coff</literal>,
|
|
<literal>elf</literal>,
|
|
<literal>as86</literal>,
|
|
<literal>obj</literal> (DOS),
|
|
<literal>win32</literal>,
|
|
<literal>rdf</literal> (their own format).
|
|
</para>
|
|
|
|
<para>
|
|
NASM can be used as a backend for the free LCC compiler
|
|
(support files included).
|
|
</para>
|
|
|
|
<para>
|
|
Unless you're using BCC as a 16-bit compiler
|
|
(which is out of scope of this 32-bit HOWTO),
|
|
you should definitely use NASM instead of say AS86 or MASM,
|
|
because it runs on all platforms.
|
|
</para>
|
|
|
|
<note><para>
|
|
NASM comes with a disassembler, NDISASM.
|
|
</para></note>
|
|
|
|
<para>
|
|
Its hand-written parser makes it much faster than GAS,
|
|
though of course, it doesn't support three bazillion different architectures.
|
|
If you like Intel-style syntax, as opposed to GAS syntax,
|
|
then it should be the assembler of choice...
|
|
</para>
|
|
|
|
<para>
|
|
Note: There are <link linkend="s-res">few programs</link>
|
|
which may help you to convert source code between AT&T and Intel assembler syntaxes;
|
|
some of the are capable of performing conversion in both directions.
|
|
</para>
|
|
|
|
</section>
|
|
|
|
</section>
|
|
|
|
<section id="p-other">
|
|
<?html-filename other.html>
|
|
<title>Other Assemblers</title>
|
|
|
|
<para>
|
|
There are other assemblers with various interesting and outstanding features
|
|
which may be of your interest as well.
|
|
</para>
|
|
|
|
<note><para>
|
|
They can be in various stages of development,
|
|
and can be non-classic/high-level/whatever else.
|
|
</para></note>
|
|
|
|
<section><title>AS86</title>
|
|
|
|
<para>
|
|
AS86 is a 80x86 assembler (16-bit and 32-bit) with integrated macro support.
|
|
It has mostly Intel-syntax, though it differs slightly as for addressing modes.
|
|
Some time ago it was used in a several projects, including the Linux kernel,
|
|
but eventually most of those projects have moved to GAS or NASM.
|
|
AFAIK, only ELKS continues to use it.
|
|
</para>
|
|
|
|
<para>
|
|
AS86 can be found at
|
|
<ulink url="http://www.cix.co.uk/~mayday/">
|
|
http://www.cix.co.uk/~mayday/</ulink>,
|
|
in bin86 package with linker (ld86), or as separate archive.
|
|
Documentation is available as the man page and as.doc from the source package.
|
|
When in doubt, the source code itself is often a good doc: though it is not
|
|
very well commented, the programming style is straightforward.
|
|
You might try to see how as86 is(was) used in ELKS, LILO, or Tunes 0.0.0.25...
|
|
</para>
|
|
|
|
<note><para>
|
|
A completely outdated version 0.4 of AS86 is distributed by HJLu
|
|
just to compile the Linux kernel versions prior to 2.4,
|
|
in a package named bin86, available in any Linux GCC repository.
|
|
But I advise no one to use it for anything else but compiling Linux.
|
|
This version supports only a hacked minix object file format,
|
|
which is not supported by the GNU binutils or anything,
|
|
and it has a few bugs in 32-bit mode,
|
|
so you really should better keep it only for compiling Linux.
|
|
</para></note>
|
|
|
|
<note>
|
|
<title>Using AS86 with BCC</title>
|
|
|
|
<para>
|
|
Here's the GNU Makefile entry for using BCC
|
|
to transform <filename>.s</filename> asm
|
|
into both a.out <filename>.o</filename> object
|
|
and <filename>.l</filename> listing:
|
|
</para>
|
|
|
|
<para><programlisting>
|
|
%.o %.l: %.s
|
|
bcc -3 -G -c -A-d -A-l -A$*.l -o $*.o $<
|
|
</programlisting></para>
|
|
|
|
<para>
|
|
Remove the <literal>%.l</literal>,
|
|
<literal>-A-l</literal>, and <literal>-A$*.l</literal>,
|
|
if you don't want any listing.
|
|
If you want something else than a.out,
|
|
you can examine BCC docs about the other supported formats,
|
|
and/or use the objcopy utility from the GNU binutils package.
|
|
</para>
|
|
</note>
|
|
|
|
</section>
|
|
|
|
<section><title>YASM</title>
|
|
|
|
<para>
|
|
YASM is a complete rewrite of the NASM assembler under the GNU GPL
|
|
(some portions are under the "new" BSD License). It is designed
|
|
from the ground up to allow for multiple syntaxes to be supported
|
|
(eg, NASM, TASM, GAS, etc.) in addition to multiple output object formats.
|
|
Another primary module of the overall design is an optimizer module.
|
|
</para>
|
|
|
|
<para>
|
|
It looks promising; it is under heavy development,
|
|
and you may want to take part.
|
|
See <ulink url="http://www.tortall.net/projects/yasm/">
|
|
http://www.tortall.net/projects/yasm/</ulink>.
|
|
</para>
|
|
|
|
</section>
|
|
|
|
<section><title>FASM</title>
|
|
<para>
|
|
FASM (flat assembler) is a fast, efficient 80x86 assembler
|
|
that runs in 'flat real mode'. Unlike many other 80x86 assemblers,
|
|
FASM only requires the source code to include the information it really needs.
|
|
It is written in itself and is very small and fast.
|
|
It runs on DOS/Windows/Linux and can produce
|
|
flat binary, DOS EXE, Win32 PE, COFF and Linux ELF output.
|
|
See <ulink url="http://flatassembler.net">http://flatassembler.net</ulink>.
|
|
</para>
|
|
</section>
|
|
|
|
<section><title>OSIMPA (SHASM)</title>
|
|
|
|
<para>
|
|
osimpa is an assembler for Intel 80386 processors and subsequent, written
|
|
entirely in the GNU Bash command interpreter shell. The predecessor of osimpa
|
|
was shasm. osimpa is much cleaned up, can create useful Linux ELF executables,
|
|
and has various HLL-like extensions and programmer convenience commands.
|
|
</para>
|
|
|
|
<para>
|
|
It is (of course) slower than other assemblers.
|
|
It has its own syntax (and uses its own names for x86 opcodes)
|
|
Fairly good documentation is included.
|
|
Check it out:
|
|
<ulink url="ftp://linux01.gwdg.de/pub/cLIeNUX/interim/">
|
|
ftp://linux01.gwdg.de/pub/cLIeNUX/interim/</ulink>.
|
|
Probably you'll not use it on regular basis,
|
|
but at least it deserves your interest as an interesting idea.
|
|
</para>
|
|
|
|
</section>
|
|
|
|
<section><title>AASM</title>
|
|
<para>
|
|
Aasm is an advanced assembler designed to support several target architectures.
|
|
It has been designed to be easily extended and, should be considered as a good
|
|
alternative to monolithic assembler development for each new target CPUs
|
|
and binary file formats.
|
|
</para>
|
|
<para>
|
|
Aasm should make assembly programming easier for developer, by providing
|
|
a set of advanced features including symbol scopes, an expressions engine,
|
|
big integer support, macro capability, numerous and accurate warning messages...
|
|
Its dynamic modular architecture enables Aasm to extend its set of features
|
|
with plug-ins by taking advantages of dynamic libraries.
|
|
</para>
|
|
<para>
|
|
The input module supports Intel syntax (like nasm, tasm, masm, etc.).
|
|
The x86 assembler module supports all opcodes up to P6 including MMX, SSE
|
|
and 3DNow! extensions. F-CPU and SPARC assembler modules are under development.
|
|
Several output modules are available for ELF, COFF, IntelHex, and raw binary formats.
|
|
</para>
|
|
<para>
|
|
<ulink url="http://savannah.nongnu.org/projects/aasm/">
|
|
http://savannah.nongnu.org/projects/aasm/</ulink>
|
|
</para>
|
|
|
|
</section>
|
|
|
|
<section><title>TDASM</title>
|
|
|
|
<para>
|
|
The Table Driven Assembler (TDASM) is a <emphasis>free</emphasis> portable
|
|
cross assembler for any kind of assembly language.
|
|
It should be possible to use it as a compiler to any target microprocessor
|
|
using a table that defines the compilation process.
|
|
</para>
|
|
|
|
<para>
|
|
It is available from <ulink url="http://www.penguin.cz/~niki/tdasm/">
|
|
http://www.penguin.cz/~niki/tdasm/</ulink>.
|
|
</para>
|
|
|
|
</section>
|
|
|
|
<section><title>HLA</title>
|
|
|
|
<para>
|
|
<ulink url="http://webster.cs.ucr.edu/AsmTools/HLA/">HLA</ulink> is a
|
|
<emphasis remap="bold">H</Emphasis>igh
|
|
<emphasis remap="bold">L</Emphasis>evel
|
|
<emphasis remap="bold">A</Emphasis>ssembly language.
|
|
It uses a high level language like syntax
|
|
(similar to Pascal, C/C++, and other HLLs) for variable declarations,
|
|
procedure declarations, and procedure calls. It uses a modified
|
|
assembly language syntax for the standard machine instructions.
|
|
It also provides several high level language style control structures
|
|
(if, while, repeat..until, etc.) that help you write much more readable code.
|
|
</para>
|
|
|
|
<para>
|
|
HLA is free and comes with source, Linux and Win32 versions available.
|
|
On Win32 you need MASM and a 32-bit version of MS-link on Win32,
|
|
on Linux you nee GAS, because HLA produces specified assembler code
|
|
and uses that assembler for final assembling and linking.
|
|
</para>
|
|
|
|
</section>
|
|
|
|
<section><title>TALC</title>
|
|
|
|
<para>
|
|
<ulink url="http://www.cs.cornell.edu/talc/">TALC</ulink>
|
|
is another free MASM/Win32 based compiler
|
|
(however it supports ELF output, does it?).
|
|
</para>
|
|
|
|
<para>
|
|
TAL stands for
|
|
<emphasis>T</emphasis>yped
|
|
<emphasis>A</Emphasis>ssembly
|
|
<emphasis>L</Emphasis>anguage.
|
|
It extends traditional untyped assembly languages with typing annotations,
|
|
memory management primitives, and a sound set of typing rules, to guarantee
|
|
the memory safety, control flow safety,and type safety of TAL programs.
|
|
Moreover, the typing constructs are expressive enough to encode
|
|
most source language programming features including records and structures,
|
|
arrays, higher-order and polymorphic functions, exceptions, abstract data types,
|
|
subtyping, and modules. Just as importantly,
|
|
TAL is flexible enough to admit many low-level compiler optimizations.
|
|
Consequently, TAL is an ideal target platform for type-directed compilers
|
|
that want to produce verifiably safe code
|
|
for use in secure mobile code applications
|
|
or extensible operating system kernels.
|
|
</para>
|
|
|
|
</section>
|
|
|
|
<section><title>Free Pascal</title>
|
|
|
|
<para>
|
|
<ulink url="http://www.freepascal.org">Free Pascal</ulink>
|
|
has an internal 32-bit assembler (based on NASM tables)
|
|
and a switchable output that allows:
|
|
<itemizedlist>
|
|
<listitem><para>
|
|
Binary (ELF and coff when crosscompiled .o) output
|
|
</para></listitem>
|
|
<listitem><para>
|
|
NASM
|
|
</para></listitem>
|
|
<listitem><para>
|
|
MASM
|
|
</para></listitem>
|
|
<listitem><para>
|
|
TASM
|
|
</para></listitem>
|
|
<listitem><para>
|
|
AS (aout,coff, elf32)
|
|
</para></listitem>
|
|
</itemizedlist>
|
|
</para>
|
|
|
|
<para>
|
|
The MASM and TASM output are not as good debugged as the other two,
|
|
but can be handy sometimes.
|
|
</para>
|
|
|
|
<para>
|
|
The assembler's look and feel are based on Turbo Pascal's internal BASM,
|
|
and the IDE supports similar highlighting, and FPC can fully integrate
|
|
with gcc (on C level, not C++).
|
|
</para>
|
|
|
|
<para>
|
|
Using a dummy RTL, one can even generate pure assembler programs.
|
|
</para>
|
|
|
|
</section>
|
|
|
|
<section><title>Win32Forth assembler</title>
|
|
|
|
<para>
|
|
Win32Forth is a <emphasis>free</emphasis> 32-bit ANS FORTH system
|
|
that successfully runs under Win32s, Win95, Win/NT.
|
|
It includes a free 32-bit assembler (either prefix or postfix syntax)
|
|
integrated into the reflective FORTH language.
|
|
Macro processing is done with
|
|
the full power of the reflective language FORTH;
|
|
however, the only supported input and output contexts is Win32For itself
|
|
(no dumping of <filename>.obj</filename> file,
|
|
but you could add that feature yourself, of course).
|
|
Find it at
|
|
<ulink url="ftp://ftp.forth.org/pub/Forth/Compilers/native/windows/Win32For/">
|
|
ftp://ftp.forth.org/pub/Forth/Compilers/native/windows/Win32For/</ulink>.
|
|
</para>
|
|
|
|
</section>
|
|
|
|
<section><title>Terse</title>
|
|
|
|
<para>
|
|
<ulink url="http://www.terse.com">Terse</ulink>
|
|
is a programming tool that provides <emphasis>THE</emphasis> most compact
|
|
assembler syntax for the x86 family!
|
|
However, it is evil proprietary software.
|
|
It is said that there was a project for a free clone somewhere,
|
|
that was abandoned after worthless pretenses that the syntax
|
|
would be owned by the original author.
|
|
Thus, if you're looking for
|
|
a nifty programming project related to assembly hacking,
|
|
I invite you to develop a terse-syntax frontend to NASM,
|
|
if you like that syntax.
|
|
</para>
|
|
|
|
<para>
|
|
As an interesting historic remark, on
|
|
<ulink URL="news:comp.compilers">comp.compilers</ulink>,
|
|
</para>
|
|
|
|
<para><literallayout>
|
|
1999/07/11 19:36:51, the moderator wrote:
|
|
|
|
"There's no reason that assemblers have to have awful syntax. About
|
|
30 years ago I used Niklaus Wirth's PL360, which was basically a S/360
|
|
assembler with Algol syntax and a a little syntactic sugar like while
|
|
loops that turned into the obvious branches. It really was an
|
|
assembler, e.g., you had to write out your expressions with explicit
|
|
assignments of values to registers, but it was nice. Wirth used it to
|
|
write Algol W, a small fast Algol subset, which was a predecessor to
|
|
Pascal. As is so often the case, Algol W was a significant
|
|
improvement over many of its successors. -John"
|
|
</literallayout></para>
|
|
|
|
</section>
|
|
|
|
<section><title>Non-free and/or Non-32bit x86 assemblers</title>
|
|
|
|
<para>
|
|
You may find more about them,
|
|
together with the basics of x86 assembly programming, in the
|
|
<link linkend="s-res-gen">Raymond Moon's x86 assembly FAQ</link>.
|
|
</para>
|
|
|
|
<para>
|
|
Note that all DOS-based assemblers should work inside the Linux DOS Emulator,
|
|
as well as other similar emulators, so that if you already own one,
|
|
you can still use it inside a real OS.
|
|
Recent DOS-based assemblers also support COFF and/or other object file formats
|
|
that are supported by the GNU BFD library,
|
|
so that you can use them together with your free 32-bit tools,
|
|
perhaps using GNU objcopy (part of the binutils) as a conversion filter.
|
|
</para>
|
|
|
|
</section>
|
|
|
|
</section>
|
|
|
|
</chapter>
|
|
|
|
|
|
<chapter id="s-meta" xreflabel="Metaprogramming">
|
|
<?html-filename metaprogramming.html>
|
|
<title>Metaprogramming</title>
|
|
|
|
<para>
|
|
Assembly programming is a bore,
|
|
but for critical parts of programs.
|
|
</para>
|
|
|
|
<para>
|
|
You should use the appropriate tool for the right task,
|
|
so don't choose assembly when it does not fit;
|
|
C, OCaml, perl, Scheme, might be a better choice
|
|
in the most cases.
|
|
</para>
|
|
|
|
<para>
|
|
However, there are cases when these tools do not give
|
|
fine enough control on the machine, and assembly is useful or needed.
|
|
In these cases you'll appreciate a system of macroprocessing and
|
|
metaprogramming that allows recurring patterns to be factored
|
|
each into one indefinitely reusable definition, which allows
|
|
safer programming, automatic propagation of pattern modification, etc.
|
|
Plain assembler often is not enough,
|
|
even when one is doing only small routines to link with C.
|
|
</para>
|
|
|
|
<section>
|
|
<?html-filename external.html>
|
|
<title>External filters</title>
|
|
|
|
<para>
|
|
Whatever is the macro support from your assembler,
|
|
or whatever language you use (even C!),
|
|
if the language is not expressive enough to you,
|
|
you can have files passed through an external filter
|
|
with a Makefile rule like that:
|
|
</para>
|
|
|
|
<para>
|
|
|
|
<programlisting>
|
|
%.s: %.S other_dependencies
|
|
$(FILTER) $(FILTER_OPTIONS) < $< > $@
|
|
</programlisting>
|
|
|
|
</para>
|
|
|
|
<section id="p-cpp" xreflabel="CPP">
|
|
<title>CPP</title>
|
|
|
|
<para>
|
|
CPP is truly not very expressive, but it's enough for easy things,
|
|
it's standard, and called transparently by GCC.
|
|
</para>
|
|
|
|
<para>
|
|
As an example of its limitations, you can't declare objects so that
|
|
destructors are automatically called at the end of the declaring block;
|
|
you don't have diversions or scoping, etc.
|
|
</para>
|
|
|
|
<para>
|
|
CPP comes with any C compiler.
|
|
However, considering how mediocre it is,
|
|
stay away from it if by chance you can make it without C.
|
|
</para>
|
|
|
|
</section>
|
|
|
|
<section id="p-m4" xreflabel="M4">
|
|
<title>M4</title>
|
|
|
|
<para>
|
|
M4 gives you the full power of macroprocessing,
|
|
with a Turing equivalent language, recursion, regular expressions, etc.
|
|
You can do with it everything that CPP cannot.
|
|
</para>
|
|
|
|
<para>
|
|
See
|
|
<ulink url="ftp://ftp.forth.org/pub/Forth/Compilers/native/unix/this4th.tar.gz">
|
|
macro4th (this4th)</ulink> or
|
|
<ulink url="ftp://ftp.tunes.org/pub/tunes/obsolete/dist/tunes.0.0.0/tunes.0.0.0.25.src.zip">
|
|
the Tunes 0.0.0.25 sources</ulink>
|
|
as examples of advanced macroprogramming using m4.
|
|
</para>
|
|
|
|
<para>
|
|
However, its disfunctional quoting and unquoting semantics force you to use
|
|
explicit continuation-passing tail-recursive macro style if
|
|
you want to do <emphasis>advanced</emphasis> macro programming
|
|
(which is remindful of TeX -- BTW, has anyone tried to use TeX as
|
|
a macroprocessor for anything else than typesetting ?).
|
|
This is NOT worse than CPP that does not allow quoting and recursion anyway.
|
|
</para>
|
|
|
|
<para>
|
|
The right version of M4 to get is <literal>GNU m4 1.4</literal>
|
|
(or later if exists),
|
|
which has the most features and the least bugs or limitations of all.
|
|
m4 is designed to be slow for anything but the simplest uses,
|
|
which might still be ok for most assembly programming
|
|
(you are not writing million-lines assembly programs, are you?).
|
|
</para>
|
|
|
|
</section>
|
|
|
|
<section><title>Macroprocessing with your own filter</title>
|
|
|
|
<para>
|
|
You can write your own simple macro-expansion filter
|
|
with the usual tools: perl, awk, sed, etc.
|
|
It can be made rather quickly, and you control everything.
|
|
But, of course, power in macroprocessing implies "the hard way".
|
|
</para>
|
|
|
|
</section>
|
|
|
|
</section>
|
|
|
|
<section>
|
|
<?html-filename meta.html>
|
|
<title>Metaprogramming</Title>
|
|
|
|
<para>
|
|
Instead of using an external filter that expands macros,
|
|
one way to do things is to write programs that write part
|
|
or all of other programs.
|
|
</para>
|
|
|
|
<para>
|
|
For instance, you could use a program outputting source code
|
|
|
|
<itemizedlist>
|
|
<listitem><para>
|
|
to generate sine/cosine/whatever lookup tables,
|
|
</para></listitem>
|
|
<listitem><para>
|
|
to extract a source-form representation of a binary file,
|
|
</para></listitem>
|
|
<listitem><para>
|
|
to compile your bitmaps into fast display routines,
|
|
</para></listitem>
|
|
<listitem><para>
|
|
to extract documentation, initialization/finalization code,
|
|
description tables, as well as normal code from the same source files,
|
|
</para></listitem>
|
|
<listitem><para>
|
|
to have customized assembly code, generated from a perl/shell/scheme script
|
|
that does arbitrary processing,
|
|
</para></listitem>
|
|
<listitem><para>
|
|
to propagate data defined at one point only
|
|
into several cross-referencing tables and code chunks.
|
|
</para></listitem>
|
|
<listitem><para>
|
|
etc.
|
|
</para></listitem>
|
|
</itemizedlist>
|
|
|
|
</para>
|
|
|
|
<para>
|
|
Think about it!
|
|
</para>
|
|
|
|
<section><title>Backends from compilers</title>
|
|
|
|
<para>
|
|
Compilers like GCC, SML/NJ, Objective CAML, MIT-Scheme, CMUCL, etc,
|
|
do have their own generic assembler backend,
|
|
which you might choose to use,
|
|
if you intend to generate code semi-automatically
|
|
from the according languages,
|
|
or from a language you hack:
|
|
rather than write great assembly code,
|
|
you may instead modify a compiler so that it dumps great assembly code!
|
|
</para>
|
|
|
|
</section>
|
|
|
|
<section><title>The New-Jersey Machine-Code Toolkit</title>
|
|
|
|
<para>
|
|
There is a project, using the programming language Icon
|
|
(with an experimental ML version),
|
|
to build a basis for producing assembly-manipulating code.
|
|
See around
|
|
<ulink url="http://www.eecs.harvard.edu/~nr/toolkit/">
|
|
http://www.eecs.harvard.edu/~nr/toolkit/</ulink>
|
|
</para>
|
|
|
|
</section>
|
|
|
|
<section><title>TUNES</title>
|
|
|
|
<para>
|
|
The <ulink url="http://www.tunes.org">TUNES Project</ulink>
|
|
for a Free Reflective Computing System
|
|
is developing its own assembler
|
|
as an extension to the Scheme language,
|
|
as part of its development process.
|
|
It doesn't run at all yet, though help is welcome.
|
|
</para>
|
|
|
|
<para>
|
|
The assembler manipulates abstract syntax trees,
|
|
so it could equally serve as the basis for a assembly syntax translator,
|
|
a disassembler, a common assembler/compiler back-end, etc.
|
|
Also, the full power of a real language, Scheme,
|
|
make it unchallenged as for macroprocessing/metaprogramming.
|
|
</para>
|
|
|
|
</section>
|
|
|
|
</section>
|
|
|
|
</chapter>
|
|
|
|
|
|
<chapter id="s-call" xreflabel="Calling conventions">
|
|
<?html-filename conventions.html>
|
|
<title>Calling conventions</title>
|
|
|
|
<section>
|
|
<?html-filename linux.html>
|
|
<title>Linux</title>
|
|
|
|
<section><title>Linking to GCC</title>
|
|
|
|
<para>
|
|
This is the preferred way if you are developing mixed C-asm project.
|
|
Check GCC docs and examples from Linux kernel <filename>.S</filename> files
|
|
that go through <application>gas</application>
|
|
(not those that go through <application>as86</application>).
|
|
</para>
|
|
|
|
<para>
|
|
32-bit arguments are pushed down stack in reverse syntactic order
|
|
(hence accessed/popped in the right order),
|
|
above the 32-bit near return address.
|
|
<literal>%ebp</literal>,
|
|
<literal>%esi</literal>,
|
|
<literal>%edi</literal>,
|
|
<literal>%ebx</literal>
|
|
are callee-saved, other registers are caller-saved;
|
|
<literal>%eax</literal> is to hold the result, or
|
|
<literal>%edx:%eax</literal> for 64-bit results.
|
|
</para>
|
|
|
|
<para>
|
|
FP stack: I'm not sure, but I think result is in
|
|
<literal>st(0)</literal>, whole stack caller-saved.
|
|
The SVR4 i386 ABI specs at
|
|
<ulink url="http://www.caldera.com/developer/devspecs/">
|
|
http://www.caldera.com/developer/devspecs/</ulink>
|
|
is a good reference point if you want more details.
|
|
</para>
|
|
|
|
<para>
|
|
Note that GCC has options to modify the calling conventions
|
|
by reserving registers, having arguments in registers,
|
|
not assuming the FPU, etc. Check the i386 <filename>.info</filename> pages.
|
|
</para>
|
|
|
|
<para>
|
|
Beware that you must then declare the <literal>cdecl</literal> or
|
|
<literal>regparm(0)</literal>
|
|
attribute for a function that will follow standard GCC calling conventions.
|
|
See <literal>C Extensions::Extended Asm::</literal> section
|
|
from the GCC info pages.
|
|
See also how Linux defines its <literal>asmlinkage</literal> macro...
|
|
</para>
|
|
|
|
</section>
|
|
|
|
<section><title>ELF vs a.out problems</title>
|
|
|
|
<para>
|
|
Some C compilers prepend an underscore before every symbol,
|
|
while others do not.
|
|
</para>
|
|
|
|
<para>
|
|
Particularly, Linux a.out GCC does such prepending,
|
|
while Linux ELF GCC does not.
|
|
</para>
|
|
|
|
<para>
|
|
If you need to cope with both behaviors at once,
|
|
see how existing packages do.
|
|
For instance, get an old Linux source tree,
|
|
the Elk, qthreads, or OCaml...
|
|
</para>
|
|
|
|
<para>
|
|
You can also override the implicit C->asm renaming
|
|
by inserting statements like
|
|
|
|
<programlisting>
|
|
void foo asm("bar") (void);
|
|
</programlisting>
|
|
|
|
to be sure that the C function <function>foo()</function>
|
|
will be called really <function>bar</function> in assembly.
|
|
</para>
|
|
|
|
<para>
|
|
Note that the <command>objcopy</command> utility from the binutils package
|
|
should allow you to transform your a.out objects into ELF objects,
|
|
and perhaps the contrary too, in some cases.
|
|
More generally, it will do lots of file format conversions.
|
|
</para>
|
|
|
|
</section>
|
|
|
|
<section><title>Direct Linux syscalls</title>
|
|
|
|
<para>
|
|
Often you will be told that using
|
|
<application>C library</application> (<acronym>libc</acronym>)
|
|
is the only way, and direct system calls are bad.
|
|
This is true. To some extent.
|
|
In general, you must know that <application>libc</application> is not sacred,
|
|
and in <emphasis>most</emphasis> cases it only does some checks,
|
|
then calls kernel, and then sets errno.
|
|
You can easily do this in your program as well (if you need to),
|
|
and your program will be dozen times smaller, and this will result
|
|
in improved performance as well, just because you're not using
|
|
shared libraries (static binaries are faster).
|
|
Using or not using <application>libc</application> in assembly programming
|
|
is more a question of taste/belief than something practical.
|
|
Remember, Linux is aiming to be POSIX compliant,
|
|
so does <application>libc</application>.
|
|
This means that syntax of almost all
|
|
<application>libc</application> "system calls"
|
|
exactly matches syntax of real kernel system calls (and vice versa).
|
|
Besides,
|
|
<application>GNU libc</application>(<application>glibc</application>)
|
|
becomes slower and slower from version to version,
|
|
and eats more and more memory; and so,
|
|
cases of using direct system calls become quite usual.
|
|
However, the main drawback of throwing <application>libc</application> away
|
|
is that you will possibly need to implement several
|
|
<application>libc</application> specific functions
|
|
(that are not just syscall wrappers) on your own
|
|
(<function>printf()</function> and Co.),
|
|
and you are ready for that, aren't you? :-)
|
|
</para>
|
|
|
|
<para>
|
|
Here is summary of direct system calls pros and cons.
|
|
</para>
|
|
|
|
<para>
|
|
Pros:
|
|
|
|
<itemizedlist>
|
|
<listitem><para>
|
|
the smallest possible size; squeezing the last byte out of the system
|
|
</para></listitem>
|
|
<listitem><para>
|
|
the highest possible speed; squeezing cycles out of your favorite benchmark
|
|
</para></listitem>
|
|
<listitem><para>
|
|
full control: you can adapt your program/library
|
|
to your specific language or memory requirements or whatever
|
|
</para></listitem>
|
|
<listitem><para>
|
|
no pollution by libc cruft
|
|
</para></listitem>
|
|
<listitem><para>
|
|
no pollution by C calling conventions
|
|
(if you're developing your own language or environment)
|
|
</para></listitem>
|
|
<listitem><para>
|
|
static binaries make you independent from libc upgrades or crashes,
|
|
or from dangling <literal>#!</literal> path to an interpreter
|
|
(and are faster)
|
|
</para></listitem>
|
|
<listitem><para>
|
|
just for the fun out of it
|
|
(don't you get a kick out of assembly programming?)
|
|
</para></listitem>
|
|
</itemizedlist>
|
|
|
|
</para>
|
|
|
|
<para>
|
|
Cons:
|
|
|
|
<itemizedlist>
|
|
<listitem><para>
|
|
If any other program on your computer uses the libc,
|
|
then duplicating the libc code will actually
|
|
wastes memory, not saves it.
|
|
</para></listitem>
|
|
<listitem><para>
|
|
Services redundantly implemented in many static binaries
|
|
are a waste of memory.
|
|
But you can make your libc replacement a shared library.
|
|
</para></listitem>
|
|
<listitem><para>
|
|
Size is much better saved by having some kind
|
|
of bytecode, wordcode, or structure interpreter
|
|
than by writing everything in assembly.
|
|
(the interpreter itself could be written either in C or assembly.)
|
|
The best way to keep multiple binaries small is
|
|
to not have multiple binaries, but instead
|
|
to have an interpreter process files with
|
|
<literal>#!</literal> prefix.
|
|
This is how OCaml works when used in wordcode mode
|
|
(as opposed to optimized native code mode),
|
|
and it is compatible with using the libc.
|
|
This is also how Tom Christiansen's
|
|
Perl PowerTools reimplementation of unix utilities works.
|
|
Finally, one last way to keep things small,
|
|
that doesn't depend on an external file with a hardcoded path,
|
|
be it library or interpreter,
|
|
is to have only one binary,
|
|
and have multiply-named hard or soft links to it:
|
|
the same binary will provide everything you need in an optimal space,
|
|
with no redundancy of subroutines or useless binary headers;
|
|
it will dispatch its specific behavior
|
|
according to its <parameter>argv[0]</parameter>;
|
|
in case it isn't called with a recognized name,
|
|
it might default to a shell,
|
|
and be possibly thus also usable as an interpreter!
|
|
</para></listitem>
|
|
<listitem><para>
|
|
You cannot benefit from the many functionalities that libc provides
|
|
besides mere linux syscalls:
|
|
that is, functionality described in section 3 of the manual pages,
|
|
as opposed to section 2,
|
|
such as malloc, threads, locale, password,
|
|
high-level network management, etc.
|
|
</para></listitem>
|
|
<listitem><para>
|
|
Therefore, you might have to reimplement large parts of libc, from
|
|
<function>printf()</function> to
|
|
<function>malloc()</function> and
|
|
<function>gethostbyname</function>.
|
|
It's redundant with the libc effort,
|
|
and can be <emphasis>quite</emphasis> boring sometimes.
|
|
Note that some people have already reimplemented "light"
|
|
replacements for parts of the libc -- check them out!
|
|
(Redhat's minilibc,
|
|
Rick Hohensee's <ulink url="ftp://linux01.gwdg.de/pub/cLIeNUX/interim/libsys.tgz">libsys</ulink>,
|
|
Felix von Leitner's <ulink url="http://www.fefe.de/dietlibc/">dietlibc</ulink>,
|
|
Christian Fowelin's <ulink url="http://www.fowelin.de/christian/computer/libASM/">libASM</ulink>,
|
|
<ulink url="http://linuxassembly.org/asmutils.html">asmutils</ulink>
|
|
project is working on pure assembly libc)
|
|
</para></listitem>
|
|
<listitem><para>
|
|
Static libraries prevent you to benefit from libc upgrades as well as from
|
|
libc add-ons such as the <application>zlibc</application> package,
|
|
that does on-the-fly transparent decompression
|
|
of gzip-compressed files.
|
|
</para></listitem>
|
|
<listitem><para>
|
|
The few instructions added by the libc can be
|
|
a <emphasis>ridiculously</emphasis> small speed overhead
|
|
as compared to the cost of a system call.
|
|
If speed is a concern, your main problem is in
|
|
your usage of system calls, not in their wrapper's implementation.
|
|
</para></listitem>
|
|
<listitem><para>
|
|
Using the standard assembly API for system calls is much slower
|
|
than using the libc API when running in micro-kernel versions
|
|
of Linux such as L4Linux,
|
|
that have their own faster calling convention,
|
|
and pay high convention-translation overhead
|
|
when using the standard one
|
|
(L4Linux comes with libc recompiled with their syscall API;
|
|
of course, you could recompile your code with their API, too).
|
|
</para></listitem>
|
|
<listitem><para>
|
|
See previous discussion for general speed optimization issue.
|
|
</para></listitem>
|
|
<listitem><para>
|
|
If syscalls are too slow to you,
|
|
you might want to hack the kernel sources (in C)
|
|
instead of staying in userland.
|
|
</para></listitem>
|
|
</itemizedlist>
|
|
|
|
</para>
|
|
|
|
<para>
|
|
If you've pondered the above pros and cons,
|
|
and still want to use direct syscalls,
|
|
then here is some advice.
|
|
</para>
|
|
|
|
<para>
|
|
|
|
<itemizedlist>
|
|
<listitem><para>
|
|
You can easily define your system calling functions
|
|
in a portable way in C (as opposed to unportable using assembly),
|
|
by including <filename>asm/unistd.h</filename>,
|
|
and using provided macros.
|
|
</para></listitem>
|
|
<listitem><para>
|
|
Since you're trying to replace it,
|
|
go get the sources for the libc, and grok them.
|
|
(And if you think you can do better,
|
|
then send feedback to the authors!)
|
|
</para></listitem>
|
|
<listitem><para>
|
|
As an example of pure assembly code that does everything you want,
|
|
examine <xref linkend="s-res">.
|
|
</para></listitem>
|
|
</itemizedlist>
|
|
|
|
</para>
|
|
|
|
<para>
|
|
Basically, you issue an <function>int 0x80</function>, with the
|
|
<literal>__NR_</literal>syscallname number
|
|
(from <filename>asm/unistd.h</filename>) in <literal>eax</literal>,
|
|
and parameters (up to <link linkend="six-arg">six</link>) in
|
|
<literal>ebx</literal>,
|
|
<literal>ecx</literal>,
|
|
<literal>edx</literal>,
|
|
<literal>esi</literal>,
|
|
<literal>edi</literal>,
|
|
<link linkend="six-arg"><literal>ebp</literal></link> respectively.
|
|
</para>
|
|
|
|
<para>
|
|
Result is returned in <literal>eax</literal>,
|
|
with a negative result being an error,
|
|
whose opposite is what libc would put into <literal>errno</literal>.
|
|
The user-stack is not touched,
|
|
so you needn't have a valid one when doing a syscall.
|
|
</para>
|
|
|
|
<note><para><anchor id="six-arg">
|
|
Passing sixth parameter in <literal>ebp</literal>
|
|
appeared in Linux 2.4, previous Linux versions understand
|
|
only 5 parameters in registers.
|
|
</para></note>
|
|
|
|
<para>
|
|
<ulink url="http://www.tldp.org/LDP/lki/">Linux Kernel Internals</ulink>,
|
|
and especially
|
|
<ulink url="http://www.tldp.org/LDP/lki/lki-2.html#ss2.11">
|
|
How System Calls Are Implemented on i386 Architecture?</ulink>
|
|
chapter will give you more robust overview.
|
|
</para>
|
|
|
|
<para>
|
|
As for the invocation arguments passed to a process upon startup,
|
|
the general principle is that the stack
|
|
originally contains the number of arguments <parameter>argc</parameter>,
|
|
then the list of pointers that constitute <parameter>*argv</parameter>,
|
|
then a null-terminated sequence of null-terminated
|
|
<literal>variable=value</literal> strings for the
|
|
<parameter>environ</parameter>ment.
|
|
For more details,
|
|
do examine <xref linkend="s-res">,
|
|
read the sources of C startup code from your libc
|
|
(<filename>crt0.S</filename> or <filename>crt1.S</filename>),
|
|
or those from the Linux kernel
|
|
(<filename>exec.c</filename> and <filename>binfmt_*.c</filename>
|
|
in <filename>linux/fs/</filename>).
|
|
</para>
|
|
|
|
</section>
|
|
|
|
<section><title>Hardware I/O under Linux</title>
|
|
|
|
<para>
|
|
If you want to perform direct port I/O under Linux,
|
|
either it's something very simple that does not need OS arbitration,
|
|
and you should see the <literal>IO-Port-Programming</literal> mini-HOWTO;
|
|
or it needs a kernel device driver, and you should try to learn more about
|
|
kernel hacking, device driver development, kernel modules, etc,
|
|
for which there are other excellent HOWTOs and documents from the LDP.
|
|
</para>
|
|
|
|
<para>
|
|
Particularly, if what you want is Graphics programming,
|
|
then do join one of the
|
|
<ulink URL="http://www.ggi-project.org/">GGI</ulink> or
|
|
<ulink URL="http://www.XFree86.org/">XFree86</ulink> projects.
|
|
</para>
|
|
|
|
<para>
|
|
Some people have even done better,
|
|
writing small and robust XFree86 drivers
|
|
in an interpreted domain-specific language, GAL,
|
|
and achieving the efficiency of hand C-written drivers
|
|
through partial evaluation (drivers not only not in asm, but not even in C!).
|
|
The problem is that the partial evaluator they used
|
|
to achieve efficiency is not free software.
|
|
Any taker for a replacement?
|
|
</para>
|
|
|
|
<para>
|
|
Anyway, in all these cases, you'll be better when using GCC inline assembly
|
|
with the macros from <filename>linux/asm/*.h</filename>
|
|
than writing full assembly source files.
|
|
</para>
|
|
|
|
</section>
|
|
|
|
<section><title>Accessing 16-bit drivers from Linux/i386</title>
|
|
|
|
<para>
|
|
Such thing is theoretically possible
|
|
(proof: see how <ulink url="http://www.dosemu.org">DOSEMU</ulink>
|
|
can selectively grant hardware port access to programs),
|
|
and I've heard rumors that someone somewhere did actually do it
|
|
(in the PCI driver? Some VESA access stuff? ISA PnP? dunno).
|
|
If you have some more precise information on that,
|
|
you'll be most welcome.
|
|
Anyway, good places to look for more information are the Linux kernel sources,
|
|
DOSEMU sources,
|
|
and sources for various low-level programs under Linux...
|
|
(perhaps GGI if it supports VESA).
|
|
</para>
|
|
|
|
<para>
|
|
Basically, you must either use 16-bit protected mode or vm86 mode.
|
|
</para>
|
|
|
|
<para>
|
|
The first is simpler to setup, but only works with well-behaved code
|
|
that won't do any kind of segment arithmetics
|
|
or absolute segment addressing (particularly addressing segment 0),
|
|
unless by chance it happens that all segments used can be setup in advance
|
|
in the LDT.
|
|
</para>
|
|
|
|
<para>
|
|
The later allows for more "compatibility" with vanilla 16-bit environments,
|
|
but requires more complicated handling.
|
|
</para>
|
|
|
|
<para>
|
|
In both cases, before you can jump to 16-bit code,
|
|
you must
|
|
|
|
<itemizedlist>
|
|
<listitem><para>
|
|
mmap any absolute address used in the 16-bit code
|
|
(such as ROM, video buffers, DMA targets, and memory-mapped I/O)
|
|
from <filename>/dev/mem</filename> to your process' address space,
|
|
</para></listitem>
|
|
<listitem><para>
|
|
setup the LDT and/or vm86 mode monitor.
|
|
</para></listitem>
|
|
<listitem><para>
|
|
grab proper I/O permissions from the kernel (see the above section)
|
|
</para></listitem>
|
|
</itemizedlist>
|
|
|
|
</para>
|
|
|
|
<para>
|
|
Again, carefully read the source for the stuff contributed
|
|
to the DOSEMU project,
|
|
particularly these mini-emulators for running ELKS
|
|
and/or simple <filename>.COM</filename> programs under Linux/i386.
|
|
</para>
|
|
|
|
</section>
|
|
|
|
</section>
|
|
|
|
<section>
|
|
<?html-filename dos.html>
|
|
<title>DOS and Windows</title>
|
|
|
|
<para>
|
|
Most DOS extenders come with some interface to DOS services.
|
|
Read their docs about that,
|
|
but often, they just simulate <function>int 0x21</function> and such,
|
|
so you do "as if" you are in real mode
|
|
(I doubt they have more than stubs
|
|
and extend things to work with 32-bit operands;
|
|
they most likely will just reflect the interrupt
|
|
into the real-mode or vm86 handler).
|
|
</para>
|
|
|
|
<para>
|
|
Docs about DPMI (and much more) can be found on
|
|
<ulink url="ftp://x2ftp.oulu.fi/pub/msdos/programming/"></ulink>
|
|
(again, the original x2ftp site is closing (no more?), so use a
|
|
<ulink url="ftp://ftp.lip6.fr/pub/pc/x2ftp/README.mirror_sites">
|
|
mirror site</ulink>).
|
|
</para>
|
|
|
|
<para>
|
|
DJGPP comes with its own (limited)
|
|
<application>glibc</application> derivative/subset/replacement, too.
|
|
</para>
|
|
|
|
<para>
|
|
It is possible to cross-compile from Linux to DOS,
|
|
see the <filename>devel/msdos/</filename> directory
|
|
of your local FTP mirror for metalab.unc.edu;
|
|
Also see the MOSS DOS-extender from the
|
|
<ulink url="http://www.cs.utah.edu/projects/flux/">Flux project</ulink>
|
|
from the university of Utah.
|
|
</para>
|
|
|
|
<para>
|
|
Other documents and FAQs are more DOS-centered;
|
|
we do not recommend DOS development.
|
|
</para>
|
|
|
|
<formalpara><title>Windows and Co.</title>
|
|
<para>
|
|
This document is not about Windows programming,
|
|
you can find lots of documents about it everywhere...
|
|
The thing you should know is that there is the
|
|
<ulink URL="http://www.cygwin.com">cygwin32.dll library</ulink>,
|
|
for GNU programs to run on Win32 platform; thus, you can use GCC, GAS,
|
|
all the GNU tools, and many other Unix applications.
|
|
</para>
|
|
</formalpara>
|
|
|
|
</section>
|
|
|
|
<section>
|
|
<?html-filename ownos.html>
|
|
<title>Your own OS</title>
|
|
|
|
<para>
|
|
Control is what attracts many OS developers to assembly,
|
|
often is what leads to or stems from assembly hacking.
|
|
Note that any system that allows self-development
|
|
could be qualified an "OS",
|
|
though it can run "on the top" of an underlying system
|
|
(much like Linux over Mach or OpenGenera over Unix).
|
|
</para>
|
|
|
|
<para>
|
|
Hence, for easier debugging purpose,
|
|
you might like to develop your "OS" first as a process running
|
|
on top of Linux (despite the slowness), then use the
|
|
<ulink url="http://www.cs.utah.edu/projects/flux/oskit/">Flux OS kit</ulink>
|
|
(which grants use of Linux and BSD drivers in your own OS)
|
|
to make it stand-alone.
|
|
When your OS is stable, it is time to write your own
|
|
hardware drivers if you really love that.
|
|
</para>
|
|
|
|
<para>
|
|
This HOWTO will not cover topics such as
|
|
bootloader code,
|
|
getting into 32-bit mode,
|
|
handling Interrupts,
|
|
the basics about Intel protected mode or V86/R86 braindeadness,
|
|
defining your object format
|
|
and calling conventions.
|
|
</para>
|
|
|
|
<para>
|
|
The main place where to find reliable information about that all,
|
|
is source code of existing OSes and bootloaders.
|
|
Lots of pointers are on the following webpage:
|
|
<ulink url="http://www.tunes.org/Review/OSes.html">
|
|
http://www.tunes.org/Review/OSes.html</ulink>
|
|
</para>
|
|
|
|
</section>
|
|
|
|
</chapter>
|
|
|
|
|
|
<chapter id="s-quick" xreflabel="Quick Start">
|
|
<?html-filename quickstart.html>
|
|
<title>Quick start</title>
|
|
|
|
<section><title>Introduction</title>
|
|
|
|
<para>
|
|
Finally, if you still want to try this crazy idea and write something in
|
|
assembly (if you've reached this section -- you're real assembly fan),
|
|
here's what you need to start.
|
|
</para>
|
|
|
|
<para>
|
|
As you've read before, you can write for Linux in different ways;
|
|
I'll show how to use <emphasis>direct</emphasis> kernel calls,
|
|
since this is the fastest way to call kernel service;
|
|
our code is not linked to any library, does not use ELF interpreter,
|
|
it communicates with kernel directly.
|
|
</para>
|
|
|
|
<para>
|
|
I will show the same sample program in two assemblers,
|
|
<command>nasm</command> and <command>gas</command>,
|
|
thus showing Intel and AT&T syntax.
|
|
</para>
|
|
|
|
<para>
|
|
You may also want to read <ulink url="http://linuxassembly.org/intro.html">
|
|
Introduction to UNIX assembly programming</ulink> tutorial,
|
|
it contains sample code for other UNIX-like OSes.
|
|
</para>
|
|
|
|
<para>
|
|
</para>
|
|
|
|
<section><title>Tools you need</title>
|
|
|
|
<para>
|
|
First of all you need assembler (compiler) --
|
|
<command>nasm</command> or <command>gas</command>.
|
|
</para>
|
|
|
|
<para>
|
|
Second, you need a linker -- <command>ld</command>,
|
|
since assembler produces only object code. Almost all distributions have
|
|
<application>gas</application> and <application>ld</application>,
|
|
in the binutils package.
|
|
</para>
|
|
|
|
<para>
|
|
As for <application>nasm</application>,
|
|
you may have to download and install binary packages for Linux and docs
|
|
from the <link linkend="p-nasm-where">nasm site</link>;
|
|
note that several distributions (Stampede, Debian, SuSe, Mandrake)
|
|
already have <application>nasm</application>, check first.
|
|
</para>
|
|
|
|
<para>
|
|
If you're going to dig in, you should also install include files for your OS,
|
|
and if possible, kernel source.
|
|
</para>
|
|
|
|
</section>
|
|
|
|
</section>
|
|
|
|
<section>
|
|
<?html-filename hello.html>
|
|
<title>Hello, world!</title>
|
|
|
|
<section><title>Program layout</title>
|
|
|
|
<para>
|
|
Linux is 32-bit, runs in protected mode, has flat memory model,
|
|
and uses the ELF format for binaries.
|
|
</para>
|
|
|
|
<para>
|
|
A program can be divided into sections:
|
|
<literal>.text</literal> for your code (read-only),
|
|
<literal>.data</literal> for your data (read-write),
|
|
<literal>.bss</literal> for uninitialized data (read-write);
|
|
there can actually be a few other standard sections,
|
|
as well as some user-defined sections,
|
|
but there's rare need to use them and they are out of our interest here.
|
|
A program must have at least <literal>.text</literal> section.
|
|
</para>
|
|
|
|
<para>
|
|
Now we will write our first program. Here is sample code:
|
|
</para>
|
|
</section>
|
|
|
|
<section><title>NASM (hello.asm)</title>
|
|
|
|
<para><programlisting>
|
|
section .text ;section declaration
|
|
|
|
;we must export the entry point to the ELF linker or
|
|
global _start ;loader. They conventionally recognize _start as their
|
|
;entry point. Use ld -e foo to override the default.
|
|
|
|
_start:
|
|
|
|
;write our string to stdout
|
|
|
|
mov edx,len ;third argument: message length
|
|
mov ecx,msg ;second argument: pointer to message to write
|
|
mov ebx,1 ;first argument: file handle (stdout)
|
|
mov eax,4 ;system call number (sys_write)
|
|
int 0x80 ;call kernel
|
|
|
|
;and exit
|
|
|
|
mov ebx,0 ;first syscall argument: exit code
|
|
mov eax,1 ;system call number (sys_exit)
|
|
int 0x80 ;call kernel
|
|
|
|
section .data ;section declaration
|
|
|
|
msg db "Hello, world!",0xa ;our dear string
|
|
len equ $ - msg ;length of our dear string
|
|
|
|
</programlisting></para>
|
|
|
|
</section>
|
|
|
|
<section><title>GAS (hello.S)</title>
|
|
|
|
<para><programlisting>
|
|
.text # section declaration
|
|
|
|
# we must export the entry point to the ELF linker or
|
|
.global _start # loader. They conventionally recognize _start as their
|
|
# entry point. Use ld -e foo to override the default.
|
|
|
|
_start:
|
|
|
|
# write our string to stdout
|
|
|
|
movl $len,%edx # third argument: message length
|
|
movl $msg,%ecx # second argument: pointer to message to write
|
|
movl $1,%ebx # first argument: file handle (stdout)
|
|
movl $4,%eax # system call number (sys_write)
|
|
int $0x80 # call kernel
|
|
|
|
# and exit
|
|
|
|
movl $0,%ebx # first argument: exit code
|
|
movl $1,%eax # system call number (sys_exit)
|
|
int $0x80 # call kernel
|
|
|
|
.data # section declaration
|
|
|
|
msg:
|
|
.ascii "Hello, world!\n" # our dear string
|
|
len = . - msg # length of our dear string
|
|
|
|
</programlisting></para>
|
|
|
|
</section>
|
|
|
|
</section>
|
|
|
|
<section>
|
|
<?html-filename build.html>
|
|
<title>Building an executable</title>
|
|
|
|
<section><title>Producing object code</title>
|
|
|
|
<para>
|
|
First step of building an executable is compiling (or assembling)
|
|
object file from the source:
|
|
</para>
|
|
|
|
<para>
|
|
For <application>nasm</application> example:
|
|
</para>
|
|
|
|
<para><screen>
|
|
$ nasm -f elf hello.asm
|
|
</screen></para>
|
|
|
|
<para>
|
|
For <application>gas</application> example:
|
|
</para>
|
|
|
|
<para><screen>
|
|
$ as -o hello.o hello.S
|
|
</screen></para>
|
|
|
|
<para>
|
|
This makes <filename>hello.o</filename> object file.
|
|
</para>
|
|
|
|
</section>
|
|
|
|
<section><title>Producing executable</title>
|
|
|
|
<para>
|
|
Second step is producing executable file itself
|
|
from the object file by invoking linker:
|
|
</para>
|
|
|
|
<para><screen>
|
|
$ ld -s -o hello hello.o
|
|
</screen></para>
|
|
|
|
<para>
|
|
This will finally build <filename>hello</filename> executable.
|
|
</para>
|
|
|
|
<para>
|
|
Hey, try to run it... Works? That's it. Pretty simple.
|
|
</para>
|
|
|
|
</section>
|
|
|
|
</section>
|
|
|
|
<section>
|
|
<?html-filename mips.html>
|
|
<title>MIPS Example</title>
|
|
|
|
<para>
|
|
As a demonstration of a fact that there's a universe other than x86,
|
|
here comes an example program for MIPS by Spencer Parkin.
|
|
BTW, if you've got here, you may also want to see
|
|
<ulink url="http://www.cuillin.demon.co.uk/nazz/trivia/hw/hw_assembler.html">
|
|
A Collection of Assembler Hello World Programs
|
|
</ulink>.
|
|
|
|
</para>
|
|
|
|
<para><programlisting><![CDATA[
|
|
# hello.S by Spencer T. Parkin
|
|
|
|
# This is my first MIPS-RISC assembly program!
|
|
# To compile this program type:
|
|
# > gcc -o hello hello.S -non_shared
|
|
|
|
# This program compiles without errors or warnings
|
|
# on a PlayStation2 MIPS R5900 (EE Core).
|
|
# EE stands for Emotion Engine...lame!
|
|
|
|
# The -non_shared option tells gcc that we`re
|
|
# not interrested in compiling relocatable code.
|
|
# If we were, we would need to follow the PIC-
|
|
# ABI calling conventions and other protocols.
|
|
|
|
#include <asm/regdef.h> // ...for human readable register names
|
|
#include <asm/unistd.h> // ...for system serivices
|
|
|
|
.rdata # begin read-only data segment
|
|
.align 2 # because of the way memory is built
|
|
hello: .asciz "Hello, world!\n" # a null terminated string
|
|
.align 4 # because of the way memory is built
|
|
length: .word . - hello # length = IC - (hello-addr)
|
|
.text # begin code segment
|
|
.globl main # for gcc/ld linking
|
|
.ent main # for gdb debugging info.
|
|
main: # We must specify -non_shared to gcc or we`ll need these 3 lines that fallow.
|
|
# .set noreorder # disable instruction reordering
|
|
# .cpload t9 # PIC ABI crap (function prologue)
|
|
# .set reorder # re-enable instruction reordering
|
|
move a0,$0 # load stdout fd
|
|
la a1,hello # load string address
|
|
lw a2,length # load string length
|
|
li v0,__NR_write # specify system write service
|
|
syscall # call the kernel (write string)
|
|
li v0,0 # load return code
|
|
j ra # return to caller
|
|
.end main # for dgb debugging info.
|
|
|
|
# That`s all folks!
|
|
]]></programlisting></para>
|
|
|
|
</section>
|
|
|
|
</chapter>
|
|
|
|
|
|
<chapter id="s-res" xreflabel="Linux assembly resources">
|
|
<?html-filename resources.html>
|
|
<title>Resources</title>
|
|
|
|
<simplesect id="s-res-url"><title>Pointers</title>
|
|
|
|
<para>
|
|
Your main resource for Linux/UNIX assembly programming material is:
|
|
</para>
|
|
|
|
<blockquote><para>
|
|
<ulink url="http://linuxassembly.org/resources.html">
|
|
http://linuxassembly.org/resources.html</ulink>
|
|
</para></blockquote>
|
|
|
|
<para>
|
|
Do visit it, and get plenty of pointers to assembly projects,
|
|
tools, tutorials, documentation, guides, etc,
|
|
concerning different UNIX operating systems and CPUs.
|
|
Because it evolves quickly, I will no longer duplicate it here.
|
|
</para>
|
|
|
|
<para>
|
|
If you are new to assembly in general, here are few starting pointers:
|
|
|
|
<anchor id="s-res-gen">
|
|
|
|
<itemizedlist>
|
|
<listitem><para>
|
|
<ulink url="http://webster.cs.ucr.edu/AoA/">The Art Of Assembly</ulink>
|
|
</para></listitem>
|
|
<listitem><para>
|
|
x86 assembly FAQ (use Google)
|
|
</para></listitem>
|
|
<listitem><para>
|
|
<ulink url="http://www.koth.org">CoreWars</ulink>,
|
|
a fun way to learn assembly in general
|
|
</para></listitem>
|
|
<listitem><para>
|
|
Usenet:
|
|
<ulink url="news://comp.lang.asm.x86">comp.lang.asm.x86</ulink>;
|
|
<ulink url="news://alt.lang.asm">alt.lang.asm</ulink>
|
|
</para></listitem>
|
|
</itemizedlist>
|
|
|
|
</para>
|
|
|
|
</simplesect>
|
|
|
|
<simplesect id="s-res-list">
|
|
<title>Mailing list</title>
|
|
|
|
<para>
|
|
If you're are interested in Linux/UNIX assembly programming
|
|
(or have questions, or are just curious)
|
|
I especially invite you to join Linux assembly programming mailing list.
|
|
</para>
|
|
|
|
<para>
|
|
This is an open discussion of assembly programming under Linux, *BSD, BeOS,
|
|
or any other UNIX/POSIX like OS; also it is not limited to x86 assembly
|
|
(Alpha, Sparc, PPC and other hackers are welcome too!).
|
|
</para>
|
|
|
|
<para>
|
|
Mailing list address is <email>linux-assembly@vger.kernel.org</email>.
|
|
</para>
|
|
|
|
<para>
|
|
To subscribe send a messgage to <email>majordomo@vger.kernel.org</email>
|
|
with the following line in the body of the message:
|
|
|
|
<programlisting>
|
|
subscribe linux-assembly
|
|
</programlisting>
|
|
</para>
|
|
|
|
<para>
|
|
Detailed information and list archives are available at
|
|
<ulink url="http://linuxassembly.org/list.html">
|
|
http://linuxassembly.org/list.html</ulink>.
|
|
</para>
|
|
|
|
</simplesect>
|
|
|
|
</chapter>
|
|
|
|
|
|
<chapter id="s-faq" xreflabel="FAQ">
|
|
<?html-filename=faq.html>
|
|
<title>Frequently Asked Questions</title>
|
|
|
|
<para>
|
|
Here are frequently asked questions (with answers)
|
|
about Linux assembly programming.
|
|
Some of the questions (and the answers) were taken from the
|
|
the <link linkend="s-res-list">linux-assembly mailing list</link>.
|
|
</para>
|
|
|
|
<qandaset defaultlabel="number">
|
|
|
|
<qandaentry>
|
|
|
|
<question><para>
|
|
How do I do graphics programming in Linux?
|
|
</para></question>
|
|
|
|
<answer>
|
|
|
|
<para>
|
|
An answer from <ulink url="mailto:paulf@gam.co.za">Paul Furber</ulink>:
|
|
</para>
|
|
|
|
<para><screen>
|
|
Ok you have a number of options to graphics in Linux. Which one you use
|
|
depends on what you want to do. There isn't one Web site with all the
|
|
information but here are some tips:
|
|
|
|
SVGALib: This is a C library for console SVGA access.
|
|
Pros: very easy to learn, good coding examples, not all that different
|
|
from equivalent gfx libraries for DOS, all the effects you know from DOS
|
|
can be converted with little difficulty.
|
|
Cons: programs need superuser rights to run since they write directly to
|
|
the hardware, doesn't work with all chipsets, can't run under X-Windows.
|
|
Search for svgalib-1.4.x on http://ftp.is.co.za
|
|
|
|
Framebuffer: do it yourself graphics at SVGA res
|
|
Pros: fast, linear mapped video access, ASM can be used if you want :)
|
|
Cons: has to be compiled into the kernel, chipset-specific issues, must
|
|
switch out of X to run, relies on good knowledge of linux system calls
|
|
and kernel, tough to debug
|
|
Examples: asmutils (http://www.linuxassembly.org) and the leaves example
|
|
and my own site for some framebuffer code and tips in asm
|
|
(http://ma.verick.co.za/linux4k/)
|
|
|
|
Xlib: the application and development libraries for XFree86.
|
|
Pros: Complete control over your X application
|
|
Cons: Difficult to learn, horrible to work with and requires quite a bit
|
|
of knowledge as to how X works at the low level.
|
|
Not recommended but if you're really masochistic go for it. All the
|
|
include and lib files are probably installed already so you have what
|
|
you need.
|
|
|
|
Low-level APIs: include PTC, SDL, GGI and Clanlib
|
|
Pros: very flexible, run under X or the console, generally abstract away
|
|
the video hardware a little so you can draw to a linear surface, lots of
|
|
good coding examples, can link to other APIs like OpenGL and sound libs,
|
|
Windows DirectX versions for free
|
|
Cons: Not as fast as doing it yourself, often in development so versions
|
|
can (and do) change frequently.
|
|
Examples: PTC and GGI have excellent demos, SDL is used in sdlQuake,
|
|
Myth II, Civ CTP and Clanlib has been used for games as well.
|
|
|
|
High-level APIs: OpenGL - any others?
|
|
Pros: clean api, tons of functionality and examples, industry standard
|
|
so you can learn from SGI demos for example
|
|
Cons: hardware acceleration is normally a must, some quirks between
|
|
versions and platforms
|
|
Examples: loads - check out www.mesa3d.org under the links section.
|
|
|
|
To get going try looking at the svgalib examples and also install SDL
|
|
and get it working. After that, the sky's the limit.
|
|
</screen></para>
|
|
|
|
</answer></qandaentry>
|
|
|
|
<qandaentry>
|
|
|
|
<question><para>
|
|
How do I debug pure assembly code under Linux?
|
|
</para></question>
|
|
|
|
<answer>
|
|
|
|
<para>
|
|
There's an early version of the
|
|
<ulink url="http://ald.sourceforge.net">Assembly Language Debugger</ulink>,
|
|
which is designed to work with assembly code,
|
|
and is portable enough to run on Linux and *BSD.
|
|
It is already functional and should be the right choice, check it out!
|
|
</para>
|
|
|
|
<para>
|
|
You can also try <command>gdb</command> ;).
|
|
Although it is source-level debugger, it can be used to debug
|
|
pure assembly code, and with some trickery you can make
|
|
<command>gdb</command> to do what you need
|
|
(unfortunately, nasm '-g' switch does not generate
|
|
proper debug info for gdb; this is nasm bug, I think).
|
|
Here's an answer from <ulink url="mailto:dl@gazeta.ru">Dmitry Bakhvalov</ulink>:
|
|
</para>
|
|
|
|
<para><screen>
|
|
Personally, I use gdb for debugging asmutils. Try this:
|
|
|
|
1) Use the following stuff to compile:
|
|
$ nasm -f elf -g smth.asm
|
|
$ ld -o smth smth.o
|
|
|
|
2) Fire up gdb:
|
|
$ gdb smth
|
|
|
|
3) In gdb:
|
|
(gdb) disassemble _start
|
|
Place a breakpoint at _start+1 (If placed at _start the breakpoint
|
|
wouldnt work, dunno why)
|
|
(gdb) b *0x8048075
|
|
|
|
To step thru the code I use the following macro:
|
|
(gdb)define n
|
|
>ni
|
|
>printf "eax=%x ebx=%x ...etc...",$eax,$ebx,...etc...
|
|
>disassemble $pc $pc+15
|
|
>end
|
|
|
|
Then start the program with r command and debug with n.
|
|
|
|
Hope this helps.
|
|
</screen></para>
|
|
|
|
<para>
|
|
An additional note from ???:
|
|
</para>
|
|
|
|
<para><screen>
|
|
I have such a macro in my .gdbinit for quite some time now, and it
|
|
for sure makes life easier. A small difference : I use "x /8i $pc",
|
|
which guarantee a fixed number of disassembled instructions. Then,
|
|
with a well chosen size for my xterm, gdb output looks like it is
|
|
refreshed, and not scrolling.
|
|
</screen></para>
|
|
|
|
<para>
|
|
If you want to set breakpoints across your code, you can just use
|
|
<function>int 3</function> instruction as breakpoint
|
|
(instead of entering address manually in <command>gdb</command>).
|
|
</para>
|
|
|
|
<para>
|
|
If you're using <application>gas</application>, you should consult
|
|
<application>gas</application> and <application>gdb</application> related
|
|
<ulink url="http://linuxassembly.org/resources.html#tutorials">tutorials</ulink>.
|
|
</para>
|
|
|
|
</answer>
|
|
|
|
</qandaentry>
|
|
|
|
<qandaentry>
|
|
|
|
<question><para>Any other useful debugging tools?</para></question>
|
|
|
|
<answer><para>
|
|
Definitely <command>strace</command> can help a lot
|
|
(<command>ktrace</command> and <command>kdump</command>
|
|
on FreeBSD),
|
|
it is used to trace system calls and signals.
|
|
Read its manual page (<command>man strace</command>) and
|
|
<command>strace --help</command> output for details.
|
|
</para></answer>
|
|
|
|
</qandaentry>
|
|
|
|
<qandaentry>
|
|
|
|
<question><para>
|
|
How do I access BIOS functions from Linux (BSD, BeOS, etc)?
|
|
</para></question>
|
|
|
|
<answer><para>
|
|
Short answer is -- noway. This is protected mode, use OS services instead.
|
|
Again, you can't use <function>int 0x10</function>,
|
|
<function>int 0x13</function>, etc.
|
|
Fortunately almost everything can be implemented
|
|
by means of system calls or library functions.
|
|
In the worst case you may go through direct port access,
|
|
or make a kernel patch to implement needed functionality,
|
|
or use LRMI library to access BIOS functions.
|
|
</para></answer>
|
|
|
|
</qandaentry>
|
|
|
|
<qandaentry>
|
|
|
|
<question><para>
|
|
Is it possible to write kernel modules in assembly?
|
|
</para></question>
|
|
|
|
<answer>
|
|
|
|
<para>
|
|
Yes, indeed it is. While in general it is not a good idea
|
|
(it hardly will speedup anything), there may be a need of such wizardy.
|
|
The process of writing a module itself is not that hard --
|
|
a module must have some predefined global function,
|
|
it may also need to call some external functions from the kernel.
|
|
Examine kernel source code (that can be built as module) for details.
|
|
</para>
|
|
|
|
<para>
|
|
Meanwhile, here's an example of a minimum dumb kernel module
|
|
(<filename>module.asm</filename>)
|
|
(source is based on example by mammon_ from APJ #8):
|
|
</para>
|
|
|
|
<para><programlisting>
|
|
section .text
|
|
|
|
global init_module
|
|
global cleanup_module
|
|
global kernel_version
|
|
|
|
extern printk
|
|
|
|
init_module:
|
|
push dword str1
|
|
call printk
|
|
pop eax
|
|
xor eax,eax
|
|
ret
|
|
|
|
cleanup_module:
|
|
push dword str2
|
|
call printk
|
|
pop eax
|
|
ret
|
|
|
|
str1 db "init_module done",0xa,0
|
|
str2 db "cleanup_module done",0xa,0
|
|
|
|
kernel_version db "2.2.18",0
|
|
</programlisting></para>
|
|
|
|
<para>
|
|
The only thing this example does is reporting its actions.
|
|
Modify <filename>kernel_version</filename> to match yours, and build module with:
|
|
</para>
|
|
|
|
<para><screen>
|
|
$ nasm -f elf -o module.m module.asm
|
|
</screen></para>
|
|
|
|
<para><screen>
|
|
$ ld -r -o module.o module.m
|
|
</screen></para>
|
|
|
|
<para>
|
|
Now you can play with it using <command>insmod/rmmod/lsmod</command>
|
|
(root privilidged are required); a lot of fun, huh?
|
|
</para>
|
|
|
|
</answer></qandaentry>
|
|
|
|
<qandaentry>
|
|
|
|
<question><para>
|
|
How do I allocate memory dynamically?
|
|
</para></question>
|
|
|
|
<answer>
|
|
<para>
|
|
A laconic answer from <ulink url="mailto:phpr@snafu.de">H-Peter Recktenwald</ulink>:
|
|
</para>
|
|
|
|
<para><programlisting>
|
|
ebx := 0 (in fact, any value below .bss seems to do)
|
|
sys_brk
|
|
eax := current top (of .bss section)
|
|
|
|
ebx := [ current top < ebx < (esp - 16K) ]
|
|
sys_brk
|
|
eax := new top of .bss
|
|
</programlisting></para>
|
|
</answer>
|
|
|
|
<answer>
|
|
<para>
|
|
An extensive answer from <ulink url="mailto:ee97034@fe.up.pt">Tiago Gasiba</ulink>:
|
|
</para>
|
|
<para><programlisting>
|
|
section .bss
|
|
|
|
var1 resb 1
|
|
|
|
section .text
|
|
|
|
;
|
|
;allocate memory
|
|
;
|
|
|
|
%define LIMIT 0x4000000 ; about 100Megs
|
|
|
|
mov ebx,0 ; get bottom of data segment
|
|
call sys_brk
|
|
|
|
cmp eax,-1 ; ok?
|
|
je erro1
|
|
|
|
add eax,LIMIT ; allocate +LIMIT memory
|
|
mov ebx,eax
|
|
call sys_brk
|
|
|
|
cmp eax,-1 ; ok?
|
|
je erro1
|
|
|
|
cmp eax,var1+1 ; has the data segment grown?
|
|
je erro1
|
|
|
|
;
|
|
;use allocated memory
|
|
;
|
|
; now eax contains bottom of
|
|
; data segment
|
|
mov ebx,eax ; save bottom
|
|
mov eax,var1 ; eax=beginning of data segment
|
|
repeat:
|
|
mov word [eax],1 ; fill up with 1's
|
|
inc eax
|
|
cmp ebx,eax ; current pos = bottom?
|
|
jne repeat
|
|
|
|
;
|
|
;free memory
|
|
;
|
|
|
|
mov ebx,var1 ; deallocate memory
|
|
call sys_brk ; by forcing its beginning=var1
|
|
|
|
cmp eax,-1 ; ok?
|
|
je erro2
|
|
</programlisting></para>
|
|
</answer>
|
|
|
|
</qandaentry>
|
|
|
|
<qandaentry>
|
|
|
|
<question><para>
|
|
I can't understand how to use <function>select</function> system call!
|
|
</para></question>
|
|
|
|
<answer>
|
|
<para>
|
|
An answer from <ulink url="mailto:mochel@transmeta.com">Patrick Mochel</ulink>:
|
|
</para>
|
|
|
|
<para><programlisting>
|
|
When you call sys_open, you get back a file descriptor, which is simply an
|
|
index into a table of all the open file descriptors that your process has.
|
|
stdin, stdout, and stderr are always 0, 1, and 2, respectively, because
|
|
that is the order in which they are always open for your process from there.
|
|
Also, notice that the first file descriptor that you open yourself (w/o first
|
|
closing any of those magic three descriptors) is always 3, and they increment
|
|
from there.
|
|
|
|
Understanding the index scheme will explain what select does. When you
|
|
call select, you are saying that you are waiting certain file descriptors
|
|
to read from, certain ones to write from, and certain ones to watch from
|
|
exceptions from. Your process can have up to 1024 file descriptors open,
|
|
so an fd_set is just a bit mask describing which file descriptors are valid
|
|
for each operation. Make sense?
|
|
|
|
Since each fd that you have open is just an index, and it only needs to be
|
|
on or off for each fd_set, you need only 1024 bits for an fd_set structure.
|
|
1024 / 32 = 32 longs needed to represent the structure.
|
|
|
|
Now, for the loose example.
|
|
Suppose you want to read from a file descriptor (w/o timeout).
|
|
|
|
- Allocate the equivalent to an fd_set.
|
|
|
|
.data
|
|
|
|
my_fds: times 32 dd 0
|
|
|
|
- open the file descriptor that you want to read from.
|
|
|
|
- set that bit in the fd_set structure.
|
|
|
|
First, you need to figure out which of the 32 dwords the bit is in.
|
|
|
|
Then, use bts to set the bit in that dword. bts will do a modulo 32
|
|
when setting the bit. That's why you need to first figure out which
|
|
dword to start with.
|
|
|
|
mov edx, 0
|
|
mov ebx, 32
|
|
div ebx
|
|
|
|
lea ebx, my_fds
|
|
bts ebx[eax * 4], edx
|
|
|
|
- repeat the last step for any file descriptors you want to read from.
|
|
|
|
- repeat the entire exercise for either of the other two fd_sets if you want action from them.
|
|
|
|
That leaves two other parts of the equation - the n paramter and the timeout
|
|
parameter. I'll leave the timeout parameter as an exercise for the reader
|
|
(yes, I'm lazy), but I'll briefly talk about the n parameter.
|
|
|
|
It is the value of the largest file descriptor you are selecting from (from
|
|
any of the fd_sets), plus one. Why plus one? Well, because it's easy to
|
|
determine a mask from that value. Suppose that there is data available on
|
|
x file descriptors, but the highest one you care about is (n - 1). Since
|
|
an fd_set is just a bitmask, the kernel needs some efficient way for
|
|
determining whether to return or not from select. So, it masks off the bits
|
|
that you care about, checks if anything is available from the bits that are
|
|
still set, and returns if there is (pause as I rummage through kernel source).
|
|
Well, it's not as easy as I fantasized it would be. To see how the kernel
|
|
determines that mask, look in fs/select.c in the kernel source tree.
|
|
|
|
Anyway, you need to know that number, and the easiest way to do it is to save
|
|
the value of the last file descriptor open somewhere so you don't lose it.
|
|
|
|
Ok, that's what I know. A warning about the code above (as always) is that
|
|
it is not tested. I think it should work, but if it doesn't let me know.
|
|
But, if it starts a global nuclear meltdown, don't call me. ;-)
|
|
</programlisting></para>
|
|
|
|
</answer></qandaentry>
|
|
|
|
</qandaset>
|
|
|
|
<para>
|
|
<emphasis>That's all for now, folks</emphasis>.
|
|
</para>
|
|
|
|
</chapter>
|
|
|
|
<!--
|
|
end
|
|
-->
|
|
|
|
|
|
<appendix id="a-history"><title>History</title>
|
|
<?html-filename history.html>
|
|
|
|
<para>
|
|
Each version includes a few fixes and minor corrections,
|
|
that need not to be repeatedly mentioned every time.
|
|
</para>
|
|
|
|
<para><revhistory>
|
|
|
|
<revision>
|
|
<revnumber>0.6g</revnumber><date>11 Feb 2006</date><authorinitials>konst</authorinitials>
|
|
<revremark>
|
|
Added AASM,
|
|
updated FASM,
|
|
added MIPS example to &s-quick; section,
|
|
added URLs to Turkish and Russian translations,
|
|
misc URL updates
|
|
</revremark>
|
|
</revision>
|
|
|
|
<revision>
|
|
<revnumber>0.6f</revnumber><date>17 Aug 2002</date><authorinitials>konst</authorinitials>
|
|
<revremark>
|
|
Added FASM,
|
|
added URL to Korean translation,
|
|
added URL to SVR4 i386 ABI specs,
|
|
update on HLA/Linux,
|
|
small fix in hello.S example,
|
|
misc URL updates
|
|
</revremark>
|
|
</revision>
|
|
|
|
<revision>
|
|
<revnumber>0.6e</revnumber><date>12 Jan 2002</date><authorinitials>konst</authorinitials>
|
|
<revremark>
|
|
Added URL describing GAS Intel syntax;
|
|
Added OSIMPA(former SHASM);
|
|
Added YASM;
|
|
FAQ update.
|
|
</revremark>
|
|
</revision>
|
|
|
|
<revision>
|
|
<revnumber>0.6d</revnumber><date>18 Mar 2001</date><authorinitials>konst</authorinitials>
|
|
<revremark>
|
|
Added Free Pascal;
|
|
new NASM URL again
|
|
</revremark>
|
|
</revision>
|
|
|
|
<revision>
|
|
<revnumber>0.6c</revnumber><date>15 Feb 2001</date><authorinitials>konst</authorinitials>
|
|
<revremark>
|
|
Added SHASM;
|
|
new answer in FAQ, new NASM URL, new mailing list address
|
|
</revremark>
|
|
</revision>
|
|
|
|
<revision>
|
|
<revnumber>0.6b</revnumber><date>21 Jan 2001</date><authorinitials>konst</authorinitials>
|
|
<revremark>
|
|
new questions in FAQ, corrected few URLs
|
|
</revremark>
|
|
</revision>
|
|
|
|
<revision>
|
|
<revnumber>0.6a</revnumber><date>10 Dec 2000</date><authorinitials>konst</authorinitials>
|
|
<revremark>
|
|
Remade section on AS86 (thanks to Holluby Istvan for pointing out
|
|
obsolete information).
|
|
Fixed several URLs that can be incorrectly rendered from sgml to html.
|
|
</revremark>
|
|
</revision>
|
|
|
|
<revision>
|
|
<revnumber>0.6</revnumber><date>11 Nov 2000</date><authorinitials>konst</authorinitials>
|
|
<revremark>
|
|
HOWTO is completely rewritten using DocBook DTD.
|
|
Layout is totally rearranged;
|
|
too much changes to list them here.
|
|
</revremark>
|
|
</revision>
|
|
|
|
<revision>
|
|
<revnumber>0.5n</revnumber><date>07 Nov 2000</date><authorinitials>konst</authorinitials>
|
|
<revremark>
|
|
Added question regarding kernel modules to &s-faq;,
|
|
fixed NASM URLs, GAS has Intel syntax too
|
|
</revremark>
|
|
</revision>
|
|
|
|
<revision>
|
|
<revnumber>0.5m</revnumber><date>22 Oct 2000</date><authorinitials>konst</authorinitials>
|
|
<revremark>
|
|
Linux 2.4 system calls can have 6 args,
|
|
Added ALD note to &s-faq;,
|
|
fixed mailing list subscribe address
|
|
</revremark>
|
|
</revision>
|
|
|
|
<revision>
|
|
<revnumber>0.5l</revnumber><date>23 Aug 2000</date><authorinitials>konst</authorinitials>
|
|
<revremark>Added TDASM, updates on NASM</revremark>
|
|
</revision>
|
|
|
|
<revision>
|
|
<revnumber>0.5k</revnumber><date>11 Jul 2000</date><authorinitials>konst</authorinitials>
|
|
<revremark>Few additions to FAQ</revremark>
|
|
</revision>
|
|
|
|
<revision>
|
|
<revnumber>0.5j</revnumber><date>14 Jun 2000</date><authorinitials>konst</authorinitials>
|
|
<revremark>
|
|
Complete rearrangement of &s-intro; and &s-res; sections.
|
|
&s-faq; added to &s-res;, misc cleanups and additions.
|
|
</revremark>
|
|
</revision>
|
|
|
|
<revision>
|
|
<revnumber>0.5i</revnumber><date>04 May 2000</date><authorinitials>konst</authorinitials>
|
|
<revremark>
|
|
Added HLA, TALC;
|
|
rearrangements in &s-res;, &s-quick; &s-assem; sections. Few new pointers.
|
|
</revremark>
|
|
</revision>
|
|
|
|
<revision>
|
|
<revnumber>0.5h</revnumber><date>09 Apr 2000</date><authorinitials>konst</authorinitials>
|
|
<revremark>
|
|
finally managed to state LDP license on document,
|
|
new resources added, misc fixes
|
|
</revremark>
|
|
</revision>
|
|
|
|
<revision>
|
|
<revnumber>0.5g</revnumber><date>26 Mar 2000</date><authorinitials>konst</authorinitials>
|
|
<revremark>new resources on different CPUs</revremark>
|
|
</revision>
|
|
|
|
<revision>
|
|
<revnumber>0.5f</revnumber><date>02 Mar 2000</date><authorinitials>konst</authorinitials>
|
|
<revremark>new resources, misc corrections</revremark>
|
|
</revision>
|
|
|
|
<revision>
|
|
<revnumber>0.5e</revnumber><date>10 Feb 2000</date><authorinitials>konst</authorinitials>
|
|
<revremark>URL updates, changes in GAS example</revremark>
|
|
</revision>
|
|
|
|
<revision>
|
|
<revnumber>0.5d</revnumber><date>01 Feb 2000</date><authorinitials>konst</authorinitials>
|
|
<revremark>
|
|
&s-res; (former "Pointers") section completely redone,
|
|
various URL updates.
|
|
</revremark>
|
|
</revision>
|
|
|
|
<revision>
|
|
<revnumber>0.5c</revnumber><date>05 Dec 1999</date><authorinitials>konst</authorinitials>
|
|
<revremark>
|
|
New pointers, updates and some rearrangements.
|
|
Rewrite of sgml source.
|
|
</revremark>
|
|
</revision>
|
|
|
|
<revision>
|
|
<revnumber>0.5b</revnumber><date>19 Sep 1999</date><authorinitials>konst</authorinitials>
|
|
<revremark>
|
|
Discussion about libc or not libc continues.
|
|
New web pointers and and overall updates.
|
|
</revremark>
|
|
</revision>
|
|
|
|
<revision>
|
|
<revnumber>0.5a</revnumber><date>01 Aug 1999</date><authorinitials>konst</authorinitials>
|
|
<revremark>
|
|
&s-quick; section rearranged, added GAS example.
|
|
Several new web pointers.
|
|
</revremark>
|
|
</revision>
|
|
|
|
<revision>
|
|
<revnumber>0.5</revnumber><date>01 Aug 1999</date>
|
|
<authorinitials>konst</authorinitials>
|
|
<authorinitials>fare</authorinitials>
|
|
<revremark>
|
|
GAS has 16-bit mode.
|
|
New maintainer (at last): Konstantin Boldyshev.
|
|
Discussion about libc or not libc.
|
|
Added &s-quick; section with examples of assembly code.
|
|
</revremark>
|
|
</revision>
|
|
|
|
<revision>
|
|
<revnumber>0.4q</revnumber><date>22 Jun 1999</date><authorinitials>fare</authorinitials>
|
|
<revremark>
|
|
process argument passing (argc, argv, environ) in assembly.
|
|
This is yet another
|
|
"last release by Fare before new maintainer takes over".
|
|
Nobody knows who might be the new maintainer.
|
|
</revremark>
|
|
</revision>
|
|
|
|
<revision>
|
|
<revnumber>0.4p</revnumber><date>06 Jun 1999</date><authorinitials>fare</authorinitials>
|
|
<revremark>clean up and updates</revremark>
|
|
</revision>
|
|
|
|
<revision>
|
|
<revnumber>0.4o</revnumber><date>01 Dec 1998</date><authorinitials>fare</authorinitials>
|
|
</revision>
|
|
|
|
<revision>
|
|
<revnumber>0.4m</revnumber><date>23 Mar 1998</date><authorinitials>fare</authorinitials>
|
|
<revremark>corrections about gcc invocation</revremark>
|
|
</revision>
|
|
|
|
<revision>
|
|
<revnumber>0.4l</revnumber><date>16 Nov 1997</date><authorinitials>fare</authorinitials>
|
|
<revremark>release for LSL 6th edition</revremark>
|
|
</revision>
|
|
|
|
<revision>
|
|
<revnumber>0.4k</revnumber><date>19 Oct 1997</date><authorinitials>fare</authorinitials>
|
|
</revision>
|
|
|
|
<revision>
|
|
<revnumber>0.4j</revnumber><date>07 Sep 1997</date><authorinitials>fare</authorinitials>
|
|
</revision>
|
|
|
|
<revision>
|
|
<revnumber>0.4i</revnumber><date>17 Jul 1997</date><authorinitials>fare</authorinitials>
|
|
<revremark>info on 16-bit mode access from Linux</revremark>
|
|
</revision>
|
|
|
|
<revision>
|
|
<revnumber>0.4h</revnumber><date>19 Jun 1997</date><authorinitials>fare</authorinitials>
|
|
<revremark>
|
|
still more on "how not to use assembly";
|
|
updates on NASM, GAS.
|
|
</revremark>
|
|
</revision>
|
|
|
|
<revision>
|
|
<revnumber>0.4g</revnumber><date>30 Mar 1997</date><authorinitials>fare</authorinitials>
|
|
</revision>
|
|
|
|
<revision>
|
|
<revnumber>0.4f</revnumber><date>20 Mar 1997</date><authorinitials>fare</authorinitials>
|
|
</revision>
|
|
|
|
<revision>
|
|
<revnumber>0.4e</revnumber><date>13 Mar 1997</date><authorinitials>fare</authorinitials>
|
|
<revremark>Release for DrLinux</revremark>
|
|
</revision>
|
|
|
|
<revision>
|
|
<revnumber>0.4d</revnumber><date>28 Feb 1997</date><authorinitials>fare</authorinitials>
|
|
<revremark>Vapor announce of a new Assembly-HOWTO maintainer</revremark>
|
|
</revision>
|
|
|
|
<revision>
|
|
<revnumber>0.4c</revnumber><date>09 Feb 1997</date>
|
|
<authorinitials>fare</authorinitials>
|
|
<revremark>Added section &s-doyou;.</revremark>
|
|
</revision>
|
|
|
|
<revision>
|
|
<revnumber>0.4b</revnumber><date>03 Feb 1997</date><authorinitials>fare</authorinitials>
|
|
<revremark>NASM moved: now is before AS86</revremark>
|
|
</revision>
|
|
|
|
<revision>
|
|
<revnumber>0.4a</revnumber><date>20 Jan 1997</date><authorinitials>fare</authorinitials>
|
|
<revremark>CREDITS section added</revremark>
|
|
</revision>
|
|
|
|
<revision>
|
|
<revnumber>0.4</revnumber><date>20 Jan 1997</date><authorinitials>fare</authorinitials>
|
|
<revremark>first release of the HOWTO as such</revremark>
|
|
</revision>
|
|
|
|
<revision>
|
|
<revnumber>0.4pre1</revnumber><date>13 Jan 1997</date><authorinitials>fare</authorinitials>
|
|
<revremark>
|
|
text mini-HOWTO transformed into a full linuxdoc-sgml HOWTO,
|
|
to see what the SGML tools are like
|
|
</revremark>
|
|
</revision>
|
|
|
|
<revision>
|
|
<revnumber>0.3l</revnumber><date>11 Jan 1997</date><authorinitials>fare</authorinitials>
|
|
</revision>
|
|
|
|
<revision>
|
|
<revnumber>0.3k</revnumber><date>19 Dec 1996</date><authorinitials>fare</authorinitials>
|
|
<revremark>What? I had forgotten to point to terse???</revremark>
|
|
</revision>
|
|
|
|
<revision>
|
|
<revnumber>0.3j</revnumber><date>24 Nov 1996</date><authorinitials>fare</authorinitials>
|
|
<revremark>point to French translated version</revremark>
|
|
</revision>
|
|
|
|
<revision>
|
|
<revnumber>0.3i</revnumber><date>16 Nov 1996</date><authorinitials>fare</authorinitials>
|
|
<revremark>NASM is getting pretty slick</revremark>
|
|
</revision>
|
|
|
|
<revision>
|
|
<revnumber>0.3h</revnumber><date>06 Nov 1996</date><authorinitials>fare</authorinitials>
|
|
<revremark>
|
|
more about cross-compiling -- See on sunsite: devel/msdos/
|
|
</revremark>
|
|
</revision>
|
|
|
|
<revision>
|
|
<revnumber>0.3g</revnumber><date>02 Nov 1996</date><authorinitials>fare</authorinitials>
|
|
<revremark>
|
|
Created the History. Added pointers in cross-compiling section.
|
|
Added section about I/O programming under Linux (particularly video).
|
|
</revremark>
|
|
</revision>
|
|
|
|
<revision>
|
|
<revnumber>0.3f</revnumber><date>17 Oct 1996</date><authorinitials>fare</authorinitials>
|
|
</revision>
|
|
|
|
<revision>
|
|
<revnumber>0.3c</revnumber><date>15 Jun 1996</date><authorinitials>fare</authorinitials>
|
|
</revision>
|
|
|
|
<revision>
|
|
<revnumber>0.2</revnumber><date>04 May 1996</date><authorinitials>fare</authorinitials>
|
|
</revision>
|
|
|
|
<revision>
|
|
<revnumber>0.1</revnumber><date>23 Apr 1996</date><authorinitials>fare</authorinitials>
|
|
<revremark>
|
|
Francois-Rene "Fare" Rideau creates and publishes the first mini-HOWTO,
|
|
because "I'm sick of answering ever the same questions
|
|
on comp.lang.asm.x86"
|
|
</revremark>
|
|
</revision>
|
|
|
|
</revhistory></para>
|
|
|
|
</appendix>
|
|
|
|
|
|
<appendix id="a-ack"><title>Acknowledgements</title>
|
|
<?html-filename acknowledgements.html>
|
|
|
|
<para>
|
|
I would like to thank all the people who have contributed ideas,
|
|
answers, remarks, and moral support, and additionally
|
|
the following persons, by order of appearance:
|
|
|
|
<itemizedlist>
|
|
<listitem><para>
|
|
<ulink URL="mailto:buried.alive@in.mail">Linus Torvalds</ulink>
|
|
for Linux
|
|
</para></listitem>
|
|
<listitem><para>
|
|
<anchor id="bde">
|
|
<ulink URL="mailto:bde@zeta.org.au">Bruce Evans</ulink>
|
|
for bcc from which as86 is extracted
|
|
</para></listitem>
|
|
<listitem><para>
|
|
<ulink URL="mailto:anakin@pobox.com">Simon Tatham</ulink> and
|
|
<ulink URL="mailto:jules@earthcorp.com">Julian Hall</ulink>
|
|
for NASM
|
|
</para></listitem>
|
|
<listitem><para>
|
|
<ulink URL="mailto:gregh@metalab.unc.edu">Greg Hankins</ulink> and now
|
|
<ulink URL="mailto:linux-howto@metalab.unc.edu">Tim Bynum</ulink>
|
|
for maintaining HOWTOs
|
|
</para></listitem>
|
|
<listitem><para>
|
|
<ulink URL="mailto:raymoon@moonware.dgsys.com">Raymond Moon</ulink>
|
|
for his FAQ
|
|
</para></listitem>
|
|
<listitem><para>
|
|
<ulink URL="mailto:dumas@linux.eu.org">Eric Dumas</ulink>
|
|
for his translation of the mini-HOWTO into French
|
|
(sad thing for the original author to be French and write in English)
|
|
</para></listitem>
|
|
<listitem><para>
|
|
<ulink URL="mailto:paul@geeky1.ebtech.net">Paul Anderson</ulink> and
|
|
<ulink URL="mailto:rahim@megsinet.net">Rahim Azizarab</ulink>
|
|
for helping me, if not for taking over the HOWTO
|
|
</para></listitem>
|
|
<listitem><para>
|
|
<ulink URL="mailto:pcg@goof.com">Marc Lehman</ulink>
|
|
for his insight on GCC invocation
|
|
</para></listitem>
|
|
<listitem><para>
|
|
<ulink URL="mailto:ams@wiw.org">Abhijit Menon-Sen</ulink>
|
|
for helping me figure out the argument passing convention
|
|
</para></listitem>
|
|
</itemizedlist>
|
|
|
|
</para>
|
|
|
|
</appendix>
|
|
|
|
|
|
<appendix id="a-endor">
|
|
<?html-filename endorsements.html>
|
|
<title>Endorsements</title>
|
|
<para>
|
|
This version of the document is endorsed by
|
|
<link linkend="konst">Konstantin Boldyshev</link>.
|
|
</para>
|
|
|
|
<para>
|
|
Modifications (including translations) must remove this appendix
|
|
according to the <link linkend="a-gfdl">license agreement</link>.
|
|
</para>
|
|
|
|
<para><literal>
|
|
$Id$
|
|
</literal></para>
|
|
</appendix>
|
|
|
|
|
|
<appendix id="a-gfdl" xreflabel="GNU Free Documentation License">
|
|
<?html-filename fdl.html>
|
|
<title>GNU Free Documentation License</title>
|
|
|
|
<para><literallayout>
|
|
GNU Free Documentation License
|
|
Version 1.1, March 2000
|
|
|
|
Copyright (C) 2000 Free Software Foundation, Inc.
|
|
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
Everyone is permitted to copy and distribute verbatim copies
|
|
of this license document, but changing it is not allowed.
|
|
</literallayout></para>
|
|
|
|
<para><variablelist>
|
|
|
|
<varlistentry><term>0. PREAMBLE</term><listitem>
|
|
|
|
<para>The purpose of this License is to make a manual, textbook,
|
|
or other written document "free" in the sense of freedom: to
|
|
assure everyone the effective freedom to copy and redistribute it,
|
|
with or without modifying it, either commercially or
|
|
noncommercially. Secondarily, this License preserves for the
|
|
author and publisher a way to get credit for their work, while not
|
|
being considered responsible for modifications made by
|
|
others.</para>
|
|
|
|
<para>This License is a kind of "copyleft", which means that
|
|
derivative works of the document must themselves be free in the
|
|
same sense. It complements the GNU General Public License, which
|
|
is a copyleft license designed for free software.</para>
|
|
|
|
<para>We have designed this License in order to use it for manuals
|
|
for free software, because free software needs free documentation:
|
|
a free program should come with manuals providing the same
|
|
freedoms that the software does. But this License is not limited
|
|
to software manuals; it can be used for any textual work,
|
|
regardless of subject matter or whether it is published as a
|
|
printed book. We recommend this License principally for works
|
|
whose purpose is instruction or reference.</para>
|
|
|
|
</listitem></varlistentry>
|
|
<varlistentry><term>1. APPLICABILITY AND DEFINITIONS</term><listitem>
|
|
|
|
<para>This License applies to any manual or other work that
|
|
contains a notice placed by the copyright holder saying it can be
|
|
distributed under the terms of this License. The "Document",
|
|
below, refers to any such manual or work. Any member of the
|
|
public is a licensee, and is addressed as "you".</para>
|
|
|
|
<para>A "Modified Version" of the Document means any work
|
|
containing the Document or a portion of it, either copied
|
|
verbatim, or with modifications and/or translated into another
|
|
language.</para>
|
|
|
|
<para>A "Secondary Section" is a named appendix or a front-matter
|
|
section of the Document that deals exclusively with the
|
|
relationship of the publishers or authors of the Document to the
|
|
Document's overall subject (or to related matters) and contains
|
|
nothing that could fall directly within that overall subject.
|
|
(For example, if the Document is in part a textbook of
|
|
mathematics, a Secondary Section may not explain any mathematics.)
|
|
The relationship could be a matter of historical connection with
|
|
the subject or with related matters, or of legal, commercial,
|
|
philosophical, ethical or political position regarding
|
|
them.</para>
|
|
|
|
<para>The "Invariant Sections" are certain Secondary Sections
|
|
whose titles are designated, as being those of Invariant Sections,
|
|
in the notice that says that the Document is released under this
|
|
License.</para>
|
|
|
|
<para>The "Cover Texts" are certain short passages of text that
|
|
are listed, as Front-Cover Texts or Back-Cover Texts, in the
|
|
notice that says that the Document is released under this
|
|
License.</para>
|
|
|
|
<para>A "Transparent" copy of the Document means a
|
|
machine-readable copy, represented in a format whose specification
|
|
is available to the general public, whose contents can be viewed
|
|
and edited directly and straightforwardly with generic text
|
|
editors or (for images composed of pixels) generic paint programs
|
|
or (for drawings) some widely available drawing editor, and that
|
|
is suitable for input to text formatters or for automatic
|
|
translation to a variety of formats suitable for input to text
|
|
formatters. A copy made in an otherwise Transparent file format
|
|
whose markup has been designed to thwart or discourage subsequent
|
|
modification by readers is not Transparent. A copy that is not
|
|
"Transparent" is called "Opaque".</para>
|
|
|
|
<para>Examples of suitable formats for Transparent copies include
|
|
plain ASCII without markup, Texinfo input format, LaTeX input
|
|
format, SGML or XML using a publicly available DTD, and
|
|
standard-conforming simple HTML designed for human modification.
|
|
Opaque formats include PostScript, PDF, proprietary formats that
|
|
can be read and edited only by proprietary word processors, SGML
|
|
or XML for which the DTD and/or processing tools are not generally
|
|
available, and the machine-generated HTML produced by some word
|
|
processors for output purposes only.</para>
|
|
|
|
<para>The "Title Page" means, for a printed book, the title page
|
|
itself, plus such following pages as are needed to hold, legibly,
|
|
the material this License requires to appear in the title page.
|
|
For works in formats which do not have any title page as such,
|
|
"Title Page" means the text near the most prominent appearance of
|
|
the work's title, preceding the beginning of the body of the
|
|
text.</para>
|
|
|
|
</listitem></varlistentry>
|
|
<varlistentry><term>2. VERBATIM COPYING</term><listitem>
|
|
|
|
<para>You may copy and distribute the Document in any medium,
|
|
either commercially or noncommercially, provided that this
|
|
License, the copyright notices, and the license notice saying this
|
|
License applies to the Document are reproduced in all copies, and
|
|
that you add no other conditions whatsoever to those of this
|
|
License. You may not use technical measures to obstruct or
|
|
control the reading or further copying of the copies you make or
|
|
distribute. However, you may accept compensation in exchange for
|
|
copies. If you distribute a large enough number of copies you
|
|
must also follow the conditions in section 3.</para>
|
|
|
|
<para>You may also lend copies, under the same conditions stated
|
|
above, and you may publicly display copies.</para>
|
|
|
|
</listitem></varlistentry>
|
|
<varlistentry><term>3. COPYING IN QUANTITY</term><listitem>
|
|
|
|
<para>If you publish printed copies of the Document numbering more
|
|
than 100, and the Document's license notice requires Cover Texts,
|
|
you must enclose the copies in covers that carry, clearly and
|
|
legibly, all these Cover Texts: Front-Cover Texts on the front
|
|
cover, and Back-Cover Texts on the back cover. Both covers must
|
|
also clearly and legibly identify you as the publisher of these
|
|
copies. The front cover must present the full title with all
|
|
words of the title equally prominent and visible. You may add
|
|
other material on the covers in addition. Copying with changes
|
|
limited to the covers, as long as they preserve the title of the
|
|
Document and satisfy these conditions, can be treated as verbatim
|
|
copying in other respects.</para>
|
|
|
|
<para>If the required texts for either cover are too voluminous to
|
|
fit legibly, you should put the first ones listed (as many as fit
|
|
reasonably) on the actual cover, and continue the rest onto
|
|
adjacent pages.</para>
|
|
|
|
<para>If you publish or distribute Opaque copies of the Document
|
|
numbering more than 100, you must either include a
|
|
machine-readable Transparent copy along with each Opaque copy, or
|
|
state in or with each Opaque copy a publicly-accessible
|
|
computer-network location containing a complete Transparent copy
|
|
of the Document, free of added material, which the general
|
|
network-using public has access to download anonymously at no
|
|
charge using public-standard network protocols. If you use the
|
|
latter option, you must take reasonably prudent steps, when you
|
|
begin distribution of Opaque copies in quantity, to ensure that
|
|
this Transparent copy will remain thus accessible at the stated
|
|
location until at least one year after the last time you
|
|
distribute an Opaque copy (directly or through your agents or
|
|
retailers) of that edition to the public.</para>
|
|
|
|
<para>It is requested, but not required, that you contact the
|
|
authors of the Document well before redistributing any large
|
|
number of copies, to give them a chance to provide you with an
|
|
updated version of the Document.</para>
|
|
|
|
</listitem></varlistentry>
|
|
<varlistentry><term>4. MODIFICATIONS</term><listitem>
|
|
|
|
<para>You may copy and distribute a Modified Version of the
|
|
Document under the conditions of sections 2 and 3 above, provided
|
|
that you release the Modified Version under precisely this
|
|
License, with the Modified Version filling the role of the
|
|
Document, thus licensing distribution and modification of the
|
|
Modified Version to whoever possesses a copy of it. In addition,
|
|
you must do these things in the Modified Version:</para>
|
|
|
|
<orderedlist numeration="upperalpha">
|
|
<listitem><para>Use in the Title Page
|
|
(and on the covers, if any) a title distinct from that of the
|
|
Document, and from those of previous versions (which should, if
|
|
there were any, be listed in the History section of the
|
|
Document). You may use the same title as a previous version if
|
|
the original publisher of that version gives permission.</para>
|
|
</listitem>
|
|
|
|
<listitem><para>List on the Title Page,
|
|
as authors, one or more persons or entities responsible for
|
|
authorship of the modifications in the Modified Version,
|
|
together with at least five of the principal authors of the
|
|
Document (all of its principal authors, if it has less than
|
|
five).</para>
|
|
</listitem>
|
|
|
|
<listitem><para>State on the Title page
|
|
the name of the publisher of the Modified Version, as the
|
|
publisher.</para>
|
|
</listitem>
|
|
|
|
<listitem><para>Preserve all the
|
|
copyright notices of the Document.</para>
|
|
</listitem>
|
|
|
|
<listitem><para>Add an appropriate
|
|
copyright notice for your modifications adjacent to the other
|
|
copyright notices.</para>
|
|
</listitem>
|
|
|
|
<listitem><para>Include, immediately
|
|
after the copyright notices, a license notice giving the public
|
|
permission to use the Modified Version under the terms of this
|
|
License, in the form shown in the Addendum below.</para>
|
|
</listitem>
|
|
|
|
<listitem><para>Preserve in that license
|
|
notice the full lists of Invariant Sections and required Cover
|
|
Texts given in the Document's license notice.</para>
|
|
</listitem>
|
|
|
|
<listitem><para>Include an unaltered
|
|
copy of this License.</para>
|
|
</listitem>
|
|
|
|
<listitem><para>Preserve the section
|
|
entitled "History", and its title, and add to it an item stating
|
|
at least the title, year, new authors, and publisher of the
|
|
Modified Version as given on the Title Page. If there is no
|
|
section entitled "History" in the Document, create one stating
|
|
the title, year, authors, and publisher of the Document as given
|
|
on its Title Page, then add an item describing the Modified
|
|
Version as stated in the previous sentence.</para>
|
|
</listitem>
|
|
|
|
<listitem><para>Preserve the network
|
|
location, if any, given in the Document for public access to a
|
|
Transparent copy of the Document, and likewise the network
|
|
locations given in the Document for previous versions it was
|
|
based on. These may be placed in the "History" section. You
|
|
may omit a network location for a work that was published at
|
|
least four years before the Document itself, or if the original
|
|
publisher of the version it refers to gives permission.</para>
|
|
</listitem>
|
|
|
|
<listitem><para>In any section entitled
|
|
"Acknowledgements" or "Dedications", preserve the section's
|
|
title, and preserve in the section all the substance and tone of
|
|
each of the contributor acknowledgements and/or dedications
|
|
given therein.</para>
|
|
</listitem>
|
|
|
|
<listitem><para>Preserve all the
|
|
Invariant Sections of the Document, unaltered in their text and
|
|
in their titles. Section numbers or the equivalent are not
|
|
considered part of the section titles.</para>
|
|
</listitem>
|
|
|
|
<listitem><para>Delete any section
|
|
entitled "Endorsements". Such a section may not be included in
|
|
the Modified Version.</para>
|
|
</listitem>
|
|
|
|
<listitem><para>Do not retitle any
|
|
existing section as "Endorsements" or to conflict in title with
|
|
any Invariant Section.</para>
|
|
</listitem>
|
|
</orderedlist>
|
|
|
|
<para>If the Modified Version includes new front-matter sections
|
|
or appendices that qualify as Secondary Sections and contain no
|
|
material copied from the Document, you may at your option
|
|
designate some or all of these sections as invariant. To do this,
|
|
add their titles to the list of Invariant Sections in the Modified
|
|
Version's license notice. These titles must be distinct from any
|
|
other section titles.</para>
|
|
|
|
<para>You may add a section entitled "Endorsements", provided it
|
|
contains nothing but endorsements of your Modified Version by
|
|
various parties--for example, statements of peer review or that
|
|
the text has been approved by an organization as the authoritative
|
|
definition of a standard.</para>
|
|
|
|
<para>You may add a passage of up to five words as a Front-Cover
|
|
Text, and a passage of up to 25 words as a Back-Cover Text, to the
|
|
end of the list of Cover Texts in the Modified Version. Only one
|
|
passage of Front-Cover Text and one of Back-Cover Text may be
|
|
added by (or through arrangements made by) any one entity. If the
|
|
Document already includes a cover text for the same cover,
|
|
previously added by you or by arrangement made by the same entity
|
|
you are acting on behalf of, you may not add another; but you may
|
|
replace the old one, on explicit permission from the previous
|
|
publisher that added the old one.</para>
|
|
|
|
<para>The author(s) and publisher(s) of the Document do not by
|
|
this License give permission to use their names for publicity for
|
|
or to assert or imply endorsement of any Modified Version.</para>
|
|
|
|
</listitem></varlistentry>
|
|
<varlistentry><term>5. COMBINING DOCUMENTS</term><listitem>
|
|
|
|
<para>You may combine the Document with other documents released
|
|
under this License, under the terms defined in section 4 above for
|
|
modified versions, provided that you include in the combination
|
|
all of the Invariant Sections of all of the original documents,
|
|
unmodified, and list them all as Invariant Sections of your
|
|
combined work in its license notice.</para>
|
|
|
|
<para>The combined work need only contain one copy of this
|
|
License, and multiple identical Invariant Sections may be replaced
|
|
with a single copy. If there are multiple Invariant Sections with
|
|
the same name but different contents, make the title of each such
|
|
section unique by adding at the end of it, in parentheses, the
|
|
name of the original author or publisher of that section if known,
|
|
or else a unique number. Make the same adjustment to the section
|
|
titles in the list of Invariant Sections in the license notice of
|
|
the combined work.</para>
|
|
|
|
<para>In the combination, you must combine any sections entitled
|
|
"History" in the various original documents, forming one section
|
|
entitled "History"; likewise combine any sections entitled
|
|
"Acknowledgements", and any sections entitled "Dedications". You
|
|
must delete all sections entitled "Endorsements."</para>
|
|
|
|
</listitem></varlistentry>
|
|
<varlistentry><term>6. COLLECTIONS OF DOCUMENTS</term><listitem>
|
|
|
|
<para>You may make a collection consisting of the Document and
|
|
other documents released under this License, and replace the
|
|
individual copies of this License in the various documents with a
|
|
single copy that is included in the collection, provided that you
|
|
follow the rules of this License for verbatim copying of each of
|
|
the documents in all other respects.</para>
|
|
|
|
<para>You may extract a single document from such a collection,
|
|
and distribute it individually under this License, provided you
|
|
insert a copy of this License into the extracted document, and
|
|
follow this License in all other respects regarding verbatim
|
|
copying of that document.</para>
|
|
|
|
</listitem></varlistentry>
|
|
<varlistentry><term>7. AGGREGATION WITH INDEPENDENT WORKS</term><listitem>
|
|
|
|
<para>A compilation of the Document or its derivatives with other
|
|
separate and independent documents or works, in or on a volume of
|
|
a storage or distribution medium, does not as a whole count as a
|
|
Modified Version of the Document, provided no compilation
|
|
copyright is claimed for the compilation. Such a compilation is
|
|
called an "aggregate", and this License does not apply to the
|
|
other self-contained works thus compiled with the Document, on
|
|
account of their being thus compiled, if they are not themselves
|
|
derivative works of the Document.</para>
|
|
|
|
<para>If the Cover Text requirement of section 3 is applicable to
|
|
these copies of the Document, then if the Document is less than
|
|
one quarter of the entire aggregate, the Document's Cover Texts
|
|
may be placed on covers that surround only the Document within the
|
|
aggregate. Otherwise they must appear on covers around the whole
|
|
aggregate.</para>
|
|
|
|
</listitem></varlistentry>
|
|
<varlistentry><term>8. TRANSLATION</term><listitem>
|
|
|
|
<para>Translation is considered a kind of modification, so you may
|
|
distribute translations of the Document under the terms of section
|
|
4. Replacing Invariant Sections with translations requires
|
|
special permission from their copyright holders, but you may
|
|
include translations of some or all Invariant Sections in addition
|
|
to the original versions of these Invariant Sections. You may
|
|
include a translation of this License provided that you also
|
|
include the original English version of this License. In case of
|
|
a disagreement between the translation and the original English
|
|
version of this License, the original English version will
|
|
prevail.</para>
|
|
|
|
</listitem></varlistentry>
|
|
<varlistentry><term>9. TERMINATION</term><listitem>
|
|
|
|
<para>You may not copy, modify, sublicense, or distribute the
|
|
Document except as expressly provided for under this License. Any
|
|
other attempt to copy, modify, sublicense or distribute the
|
|
Document is void, and will automatically terminate your rights
|
|
under this License. However, parties who have received copies, or
|
|
rights, from you under this License will not have their licenses
|
|
terminated so long as such parties remain in full
|
|
compliance.</para>
|
|
|
|
</listitem></varlistentry>
|
|
<varlistentry><term>10. FUTURE REVISIONS OF THIS LICENSE</term><listitem>
|
|
|
|
<para>The Free Software Foundation may publish new, revised
|
|
versions of the GNU Free Documentation License from time to time.
|
|
Such new versions will be similar in spirit to the present
|
|
version, but may differ in detail to address new problems or
|
|
concerns. See <ulink
|
|
url="http://www.gnu.org/copyleft/">http://www.gnu.org/copyleft/</ulink>.</para>
|
|
|
|
<para>Each version of the License is given a distinguishing
|
|
version number. If the Document specifies that a particular
|
|
numbered version of this License "or any later version" applies to
|
|
it, you have the option of following the terms and conditions
|
|
either of that specified version or of any later version that has
|
|
been published (not as a draft) by the Free Software Foundation.
|
|
If the Document does not specify a version number of this License,
|
|
you may choose any version ever published (not as a draft) by the
|
|
Free Software Foundation.</para>
|
|
|
|
</listitem></varlistentry>
|
|
<varlistentry><term>How to use this License for your documents</term>
|
|
<listitem>
|
|
|
|
<para>To use this License in a document you have written, include
|
|
a copy of the License in the document and put the following
|
|
copyright and license notices just after the title page:</para>
|
|
|
|
<para><literallayout>
|
|
Copyright (c) YEAR YOUR NAME.
|
|
Permission is granted to copy, distribute and/or modify this document
|
|
under the terms of the GNU Free Documentation License, Version 1.1
|
|
or any later version published by the Free Software Foundation;
|
|
with the Invariant Sections being LIST THEIR TITLES, with the
|
|
Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST.
|
|
A copy of the license is included in the section entitled "GNU
|
|
Free Documentation License".
|
|
</literallayout></para>
|
|
|
|
<para>If you have no Invariant Sections, write "with no Invariant
|
|
Sections" instead of saying which ones are invariant. If you have
|
|
no Front-Cover Texts, write "no Front-Cover Texts" instead of
|
|
"Front-Cover Texts being LIST"; likewise for Back-Cover
|
|
Texts.</para>
|
|
|
|
<para>If your document contains nontrivial examples of program
|
|
code, we recommend releasing these examples in parallel under your
|
|
choice of free software license, such as the GNU General Public
|
|
License, to permit their use in free software.</para>
|
|
|
|
</listitem></varlistentry>
|
|
|
|
</variablelist></para>
|
|
|
|
</appendix>
|
|
|
|
</book>
|