6256 lines
134 KiB
HTML
6256 lines
134 KiB
HTML
<HTML
|
|
><HEAD
|
|
><TITLE
|
|
>Linux Assembly HOWTO</TITLE
|
|
><META
|
|
NAME="GENERATOR"
|
|
CONTENT="Modular DocBook HTML Stylesheet Version 1.76b+
|
|
"><META
|
|
NAME="KEYWORD"
|
|
CONTENT="assembly"><META
|
|
NAME="KEYWORD"
|
|
CONTENT="assembler"><META
|
|
NAME="KEYWORD"
|
|
CONTENT="asm"><META
|
|
NAME="KEYWORD"
|
|
CONTENT="inline"><META
|
|
NAME="KEYWORD"
|
|
CONTENT="32-bit"><META
|
|
NAME="KEYWORD"
|
|
CONTENT="IA-32"><META
|
|
NAME="KEYWORD"
|
|
CONTENT="i386"><META
|
|
NAME="KEYWORD"
|
|
CONTENT="x86"><META
|
|
NAME="KEYWORD"
|
|
CONTENT="nasm"><META
|
|
NAME="KEYWORD"
|
|
CONTENT="gas"><META
|
|
NAME="KEYWORD"
|
|
CONTENT="as"><META
|
|
NAME="KEYWORD"
|
|
CONTENT="as86"><META
|
|
NAME="KEYWORD"
|
|
CONTENT="yasm"><META
|
|
NAME="KEYWORD"
|
|
CONTENT="shasm"><META
|
|
NAME="KEYWORD"
|
|
CONTENT="osimpa"><META
|
|
NAME="KEYWORD"
|
|
CONTENT="OS"><META
|
|
NAME="KEYWORD"
|
|
CONTENT="Linux"><META
|
|
NAME="KEYWORD"
|
|
CONTENT="Unix"><META
|
|
NAME="KEYWORD"
|
|
CONTENT="kernel"><META
|
|
NAME="KEYWORD"
|
|
CONTENT="system"><META
|
|
NAME="KEYWORD"
|
|
CONTENT="libc"><META
|
|
NAME="KEYWORD"
|
|
CONTENT="glibc"><META
|
|
NAME="KEYWORD"
|
|
CONTENT="system call"><META
|
|
NAME="KEYWORD"
|
|
CONTENT="interrupt"><META
|
|
NAME="KEYWORD"
|
|
CONTENT="small"><META
|
|
NAME="KEYWORD"
|
|
CONTENT="fast"><META
|
|
NAME="KEYWORD"
|
|
CONTENT="embedded"><META
|
|
NAME="KEYWORD"
|
|
CONTENT="hardware"><META
|
|
NAME="KEYWORD"
|
|
CONTENT="port"><META
|
|
NAME="KEYWORD"
|
|
CONTENT="macroprocessor"><META
|
|
NAME="KEYWORD"
|
|
CONTENT="metaprogramming"><META
|
|
NAME="KEYWORD"
|
|
CONTENT="preprocessor"></HEAD
|
|
><BODY
|
|
CLASS="BOOK"
|
|
BGCOLOR="#FFFFFF"
|
|
TEXT="#000000"
|
|
LINK="#0000FF"
|
|
VLINK="#840084"
|
|
ALINK="#0000FF"
|
|
><DIV
|
|
CLASS="BOOK"
|
|
><A
|
|
NAME="AEN1"><DIV
|
|
CLASS="TITLEPAGE"
|
|
><H1
|
|
CLASS="TITLE"
|
|
><A
|
|
NAME="AEN2">Linux Assembly HOWTO</H1
|
|
><H3
|
|
CLASS="AUTHOR"
|
|
><A
|
|
NAME="AEN5">Konstantin Boldyshev</H3
|
|
><DIV
|
|
CLASS="AFFILIATION"
|
|
><SPAN
|
|
CLASS="ORGNAME"
|
|
> <A
|
|
HREF="http://linuxassembly.org"
|
|
TARGET="_top"
|
|
> Linux Assembly<A
|
|
NAME="KONST"
|
|
></A
|
|
></A
|
|
>
|
|
<BR></SPAN
|
|
><DIV
|
|
CLASS="ADDRESS"
|
|
><P
|
|
CLASS="ADDRESS"
|
|
> konst@linuxassembly.org<br>
|
|
</P
|
|
></DIV
|
|
></DIV
|
|
><H3
|
|
CLASS="AUTHOR"
|
|
><A
|
|
NAME="AEN14">Francois-Rene Rideau</H3
|
|
><DIV
|
|
CLASS="AFFILIATION"
|
|
><SPAN
|
|
CLASS="ORGNAME"
|
|
> <A
|
|
HREF="http://tunes.org"
|
|
TARGET="_top"
|
|
> Tunes project<A
|
|
NAME="FARE"
|
|
></A
|
|
></A
|
|
>
|
|
<BR></SPAN
|
|
><DIV
|
|
CLASS="ADDRESS"
|
|
><P
|
|
CLASS="ADDRESS"
|
|
> fare@tunes.org<br>
|
|
</P
|
|
></DIV
|
|
></DIV
|
|
><P
|
|
CLASS="COPYRIGHT"
|
|
>Copyright © 1999-2002 by Konstantin Boldyshev</P
|
|
><P
|
|
CLASS="COPYRIGHT"
|
|
>Copyright © 1996-1999 by Francois-Rene Rideau</P
|
|
><P
|
|
CLASS="PUBDATE"
|
|
>$Date: 2002/08/17 08:35:59 $<BR></P
|
|
><DIV
|
|
><DIV
|
|
CLASS="ABSTRACT"
|
|
><A
|
|
NAME="AEN34"><P
|
|
></P
|
|
><P
|
|
>This is the Linux Assembly HOWTO, version 0.6f.
|
|
This document describes how to program in assembly language
|
|
using <EM
|
|
>free</EM
|
|
> 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.</P
|
|
><P
|
|
></P
|
|
></DIV
|
|
></DIV
|
|
><DIV
|
|
CLASS="LEGALNOTICE"
|
|
><A
|
|
NAME="AEN29"><P
|
|
></P
|
|
><P
|
|
>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.</P
|
|
><P
|
|
></P
|
|
></DIV
|
|
><HR></DIV
|
|
><DIV
|
|
CLASS="TOC"
|
|
><DL
|
|
><DT
|
|
><B
|
|
>Table of Contents</B
|
|
></DT
|
|
><DT
|
|
>1. <A
|
|
HREF="#S-INTRO"
|
|
>Introduction</A
|
|
></DT
|
|
><DD
|
|
><DL
|
|
><DT
|
|
>1.1. <A
|
|
HREF="#AEN74"
|
|
>Legal Blurb</A
|
|
></DT
|
|
><DT
|
|
>1.2. <A
|
|
HREF="#AEN82"
|
|
>Foreword</A
|
|
></DT
|
|
><DT
|
|
>1.3. <A
|
|
HREF="#AEN99"
|
|
>Contributions</A
|
|
></DT
|
|
><DT
|
|
>1.4. <A
|
|
HREF="#AEN110"
|
|
>Translations</A
|
|
></DT
|
|
></DL
|
|
></DD
|
|
><DT
|
|
>2. <A
|
|
HREF="#S-DOYOU"
|
|
>Do you need assembly?</A
|
|
></DT
|
|
><DD
|
|
><DL
|
|
><DT
|
|
>2.1. <A
|
|
HREF="#AEN117"
|
|
>Pros and Cons</A
|
|
></DT
|
|
><DT
|
|
>2.2. <A
|
|
HREF="#AEN187"
|
|
>How to NOT use Assembly</A
|
|
></DT
|
|
><DT
|
|
>2.3. <A
|
|
HREF="#AEN230"
|
|
>Linux and assembly</A
|
|
></DT
|
|
></DL
|
|
></DD
|
|
><DT
|
|
>3. <A
|
|
HREF="#S-ASSEM"
|
|
>Assemblers</A
|
|
></DT
|
|
><DD
|
|
><DL
|
|
><DT
|
|
>3.1. <A
|
|
HREF="#P-GCC"
|
|
>GCC Inline Assembly</A
|
|
></DT
|
|
><DT
|
|
>3.2. <A
|
|
HREF="#P-GAS"
|
|
>GAS</A
|
|
></DT
|
|
><DT
|
|
>3.3. <A
|
|
HREF="#P-NASM"
|
|
>NASM</A
|
|
></DT
|
|
><DT
|
|
>3.4. <A
|
|
HREF="#P-AS86"
|
|
>AS86</A
|
|
></DT
|
|
><DT
|
|
>3.5. <A
|
|
HREF="#P-OTHER"
|
|
>Other Assemblers</A
|
|
></DT
|
|
></DL
|
|
></DD
|
|
><DT
|
|
>4. <A
|
|
HREF="#S-META"
|
|
>Metaprogramming</A
|
|
></DT
|
|
><DD
|
|
><DL
|
|
><DT
|
|
>4.1. <A
|
|
HREF="#AEN565"
|
|
>External filters</A
|
|
></DT
|
|
><DT
|
|
>4.2. <A
|
|
HREF="#AEN588"
|
|
>Metaprogramming</A
|
|
></DT
|
|
></DL
|
|
></DD
|
|
><DT
|
|
>5. <A
|
|
HREF="#S-CALL"
|
|
>Calling conventions</A
|
|
></DT
|
|
><DD
|
|
><DL
|
|
><DT
|
|
>5.1. <A
|
|
HREF="#AEN622"
|
|
>Linux</A
|
|
></DT
|
|
><DT
|
|
>5.2. <A
|
|
HREF="#AEN801"
|
|
>DOS and Windows</A
|
|
></DT
|
|
><DT
|
|
>5.3. <A
|
|
HREF="#AEN819"
|
|
>Your own OS</A
|
|
></DT
|
|
></DL
|
|
></DD
|
|
><DT
|
|
>6. <A
|
|
HREF="#S-QUICK"
|
|
>Quick start</A
|
|
></DT
|
|
><DD
|
|
><DL
|
|
><DT
|
|
>6.1. <A
|
|
HREF="#AEN829"
|
|
>Introduction</A
|
|
></DT
|
|
><DT
|
|
>6.2. <A
|
|
HREF="#AEN853"
|
|
>Hello, world!</A
|
|
></DT
|
|
><DT
|
|
>6.3. <A
|
|
HREF="#AEN872"
|
|
>Building an executable</A
|
|
></DT
|
|
></DL
|
|
></DD
|
|
><DT
|
|
>7. <A
|
|
HREF="#S-RES"
|
|
>Resources</A
|
|
></DT
|
|
><DD
|
|
><DL
|
|
><DT
|
|
>7.1. <A
|
|
HREF="#S-RES-URL"
|
|
>Pointers</A
|
|
></DT
|
|
><DT
|
|
>7.2. <A
|
|
HREF="#S-RES-LIST"
|
|
>Mailing list</A
|
|
></DT
|
|
></DL
|
|
></DD
|
|
><DT
|
|
>8. <A
|
|
HREF="#S-FAQ"
|
|
>Frequently Asked Questions</A
|
|
></DT
|
|
><DT
|
|
>A. <A
|
|
HREF="#A-HISTORY"
|
|
>History</A
|
|
></DT
|
|
><DT
|
|
>B. <A
|
|
HREF="#A-ACK"
|
|
>Acknowledgements</A
|
|
></DT
|
|
><DT
|
|
>C. <A
|
|
HREF="#A-ENDOR"
|
|
>Endorsements</A
|
|
></DT
|
|
><DT
|
|
>D. <A
|
|
HREF="#A-GFDL"
|
|
>GNU Free Documentation License</A
|
|
></DT
|
|
></DL
|
|
></DIV
|
|
><DIV
|
|
CLASS="CHAPTER"
|
|
><HR><H1
|
|
><A
|
|
NAME="S-INTRO">Chapter 1. Introduction</H1
|
|
><DIV
|
|
CLASS="NOTE"
|
|
><P
|
|
></P
|
|
><TABLE
|
|
CLASS="NOTE"
|
|
WIDTH="100%"
|
|
BORDER="0"
|
|
><TR
|
|
><TD
|
|
WIDTH="25"
|
|
ALIGN="CENTER"
|
|
VALIGN="TOP"
|
|
><IMG
|
|
SRC="../images/note.gif"
|
|
HSPACE="5"
|
|
ALT="Note"></TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
><P
|
|
>You can skip this chapter if you are familiar with HOWTOs,
|
|
or just hate to read all this assembly-unrelated crap.</P
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></DIV
|
|
><DIV
|
|
CLASS="SIMPLESECT"
|
|
><HR><H4
|
|
CLASS="SIMPLESECT"
|
|
><A
|
|
NAME="AEN74">1.1. Legal Blurb</H4
|
|
><P
|
|
>Permission is granted to copy, distribute and/or modify this document
|
|
under the terms of the GNU
|
|
<A
|
|
HREF="http://www.gnu.org/copyleft/fdl.html"
|
|
TARGET="_top"
|
|
>Free Documentation License</A
|
|
> 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 <A
|
|
HREF="#A-GFDL"
|
|
>GNU Free Documentation License</A
|
|
> appendix.</P
|
|
><P
|
|
>The most recent official version of this document is available from the
|
|
<A
|
|
HREF="http://linuxassembly.org/howto.html"
|
|
TARGET="_top"
|
|
>Linux Assembly</A
|
|
> and
|
|
<A
|
|
HREF="http://linuxdoc.org/docs.html"
|
|
TARGET="_top"
|
|
>LDP</A
|
|
> sites.
|
|
If you are reading a few-months-old copy,
|
|
consider checking the above URLs for a new version.</P
|
|
></DIV
|
|
><DIV
|
|
CLASS="SIMPLESECT"
|
|
><HR><H4
|
|
CLASS="SIMPLESECT"
|
|
><A
|
|
NAME="AEN82">1.2. Foreword</H4
|
|
><P
|
|
>This document aims answering questions of those
|
|
who program or want to program 32-bit x86 assembly using
|
|
<EM
|
|
>free software</EM
|
|
>,
|
|
particularly under the Linux operating system.
|
|
At many places Universal Resource Locators (<SPAN
|
|
CLASS="ACRONYM"
|
|
>URL</SPAN
|
|
>) 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.</P
|
|
><P
|
|
>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.</P
|
|
><P
|
|
>If you don't know what
|
|
<A
|
|
HREF="http://www.gnu.org/philosophy/"
|
|
TARGET="_top"
|
|
><EM
|
|
>free software</EM
|
|
></A
|
|
> is,
|
|
please do read <EM
|
|
>carefully</EM
|
|
>
|
|
the GNU <A
|
|
HREF="http://www.gnu.org/copyleft/gpl.html"
|
|
TARGET="_top"
|
|
>General Public License</A
|
|
>
|
|
(<SPAN
|
|
CLASS="ACRONYM"
|
|
>GPL</SPAN
|
|
> or <SPAN
|
|
CLASS="ACRONYM"
|
|
>copyleft</SPAN
|
|
>),
|
|
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 <TT
|
|
CLASS="FILENAME"
|
|
>COPYING</TT
|
|
>
|
|
(or <TT
|
|
CLASS="FILENAME"
|
|
>COPYING.LIB</TT
|
|
>).
|
|
Literature from the
|
|
<A
|
|
HREF="http://www.fsf.org"
|
|
TARGET="_top"
|
|
>Free Software Foundation</A
|
|
>
|
|
(<SPAN
|
|
CLASS="ACRONYM"
|
|
>FSF</SPAN
|
|
>) 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.</P
|
|
></DIV
|
|
><DIV
|
|
CLASS="SIMPLESECT"
|
|
><HR><H4
|
|
CLASS="SIMPLESECT"
|
|
><A
|
|
NAME="AEN99">1.3. Contributions</H4
|
|
><P
|
|
>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!</P
|
|
><P
|
|
>To contribute, please contact the <A
|
|
HREF="#KONST"
|
|
>maintainer</A
|
|
>.</P
|
|
><DIV
|
|
CLASS="NOTE"
|
|
><P
|
|
></P
|
|
><TABLE
|
|
CLASS="NOTE"
|
|
WIDTH="100%"
|
|
BORDER="0"
|
|
><TR
|
|
><TD
|
|
WIDTH="25"
|
|
ALIGN="CENTER"
|
|
VALIGN="TOP"
|
|
><IMG
|
|
SRC="../images/note.gif"
|
|
HSPACE="5"
|
|
ALT="Note"></TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
><P
|
|
>At the time of writing, it is
|
|
<A
|
|
HREF="#KONST"
|
|
>Konstantin Boldyshev</A
|
|
>
|
|
and no more
|
|
<A
|
|
HREF="#FARE"
|
|
>Francois-Rene Rideau</A
|
|
> (since version 0.5).
|
|
I (<A
|
|
HREF="#FARE"
|
|
>Fare</A
|
|
>) had been looking for some time
|
|
for a serious hacker to replace me as maintainer of this document,
|
|
and am pleased to announce
|
|
<A
|
|
HREF="#KONST"
|
|
>Konstantin</A
|
|
> as my worthy successor.</P
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></DIV
|
|
></DIV
|
|
><DIV
|
|
CLASS="SIMPLESECT"
|
|
><HR><H4
|
|
CLASS="SIMPLESECT"
|
|
><A
|
|
NAME="AEN110">1.4. Translations</H4
|
|
><P
|
|
>Korean translation of this HOWTO is avalilable at
|
|
<A
|
|
HREF="http://kldp.org/HOWTO/html/Assembly-HOWTO/"
|
|
TARGET="_top"
|
|
>http://kldp.org/HOWTO/html/Assembly-HOWTO/</A
|
|
>.
|
|
Also, there was French translation of the early HOWTO versions,
|
|
but I couldn't find it now.</P
|
|
></DIV
|
|
></DIV
|
|
><DIV
|
|
CLASS="CHAPTER"
|
|
><HR><H1
|
|
><A
|
|
NAME="S-DOYOU">Chapter 2. Do you need assembly?</H1
|
|
><P
|
|
>Well, I wouldn't want to interfere with what you're doing,
|
|
but here is some advice from the hard-earned experience.</P
|
|
><DIV
|
|
CLASS="SECTION"
|
|
><HR><H1
|
|
CLASS="SECTION"
|
|
><A
|
|
NAME="AEN117">2.1. Pros and Cons</H1
|
|
><DIV
|
|
CLASS="SECTION"
|
|
><H2
|
|
CLASS="SECTION"
|
|
><A
|
|
NAME="AEN119">2.1.1. The advantages of Assembly</H2
|
|
><P
|
|
>Assembly can express very low-level things:
|
|
|
|
<P
|
|
></P
|
|
><UL
|
|
><LI
|
|
><P
|
|
>you can access machine-dependent registers and I/O</P
|
|
></LI
|
|
><LI
|
|
><P
|
|
>you can control the exact code behavior
|
|
in critical sections that might otherwise involve deadlock
|
|
between multiple software threads or hardware devices</P
|
|
></LI
|
|
><LI
|
|
><P
|
|
>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)</P
|
|
></LI
|
|
><LI
|
|
><P
|
|
>you can build interfaces between code fragments
|
|
using incompatible conventions
|
|
(e.g. produced by different compilers,
|
|
or separated by a low-level interface)</P
|
|
></LI
|
|
><LI
|
|
><P
|
|
>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)</P
|
|
></LI
|
|
><LI
|
|
><P
|
|
>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!)</P
|
|
></LI
|
|
><LI
|
|
><P
|
|
>you can produce hand-optimized code
|
|
perfectly tuned for your particular hardware setup,
|
|
though not to someone else's</P
|
|
></LI
|
|
><LI
|
|
><P
|
|
>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)</P
|
|
></LI
|
|
><LI
|
|
><P
|
|
>i.e. you can be in complete control of your code</P
|
|
></LI
|
|
></UL
|
|
> </P
|
|
></DIV
|
|
><DIV
|
|
CLASS="SECTION"
|
|
><HR><H2
|
|
CLASS="SECTION"
|
|
><A
|
|
NAME="AEN141">2.1.2. The disadvantages of Assembly</H2
|
|
><P
|
|
>Assembly is a very low-level language
|
|
(the lowest above hand-coding the binary instruction patterns).
|
|
This means
|
|
|
|
<P
|
|
></P
|
|
><UL
|
|
><LI
|
|
><P
|
|
>it is long and tedious to write initially</P
|
|
></LI
|
|
><LI
|
|
><P
|
|
>it is quite bug-prone</P
|
|
></LI
|
|
><LI
|
|
><P
|
|
>your bugs can be very difficult to chase</P
|
|
></LI
|
|
><LI
|
|
><P
|
|
>your code can be fairly difficult to understand and modify,
|
|
i.e. to maintain</P
|
|
></LI
|
|
><LI
|
|
><P
|
|
>the result is non-portable to other architectures,
|
|
existing or upcoming</P
|
|
></LI
|
|
><LI
|
|
><P
|
|
>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.</P
|
|
></LI
|
|
><LI
|
|
><P
|
|
>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)</P
|
|
></LI
|
|
><LI
|
|
><P
|
|
>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</P
|
|
></LI
|
|
><LI
|
|
><P
|
|
>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);</P
|
|
></LI
|
|
><LI
|
|
><P
|
|
>And in any case, as says moderator John Levine on
|
|
<A
|
|
HREF="news:comp.compilers"
|
|
TARGET="_top"
|
|
>comp.compilers</A
|
|
>,</P
|
|
><P
|
|
CLASS="LITERALLAYOUT"
|
|
>"compilers make it a lot easier to use complex data structures,<br>
|
|
and compilers don't get bored halfway through<br>
|
|
and generate reliably pretty good code."</P
|
|
><P
|
|
>They will also <EM
|
|
>correctly</EM
|
|
> propagate code transformations
|
|
throughout the whole (huge) program
|
|
when optimizing code between procedures and module boundaries.</P
|
|
></LI
|
|
></UL
|
|
> </P
|
|
></DIV
|
|
><DIV
|
|
CLASS="SECTION"
|
|
><HR><H2
|
|
CLASS="SECTION"
|
|
><A
|
|
NAME="AEN169">2.1.3. Assessment</H2
|
|
><P
|
|
>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:
|
|
|
|
<P
|
|
></P
|
|
><UL
|
|
><LI
|
|
><P
|
|
>minimize use of assembly code</P
|
|
></LI
|
|
><LI
|
|
><P
|
|
>encapsulate this code in well-defined interfaces</P
|
|
></LI
|
|
><LI
|
|
><P
|
|
>have your assembly code automatically generated
|
|
from patterns expressed in a higher-level language
|
|
than assembly (e.g. GCC inline assembly macros)</P
|
|
></LI
|
|
><LI
|
|
><P
|
|
>have automatic tools translate these programs
|
|
into assembly code</P
|
|
></LI
|
|
><LI
|
|
><P
|
|
>have this code be optimized if possible</P
|
|
></LI
|
|
><LI
|
|
><P
|
|
>All of the above,
|
|
i.e. write (an extension to) an optimizing compiler back-end.</P
|
|
></LI
|
|
></UL
|
|
> </P
|
|
><P
|
|
>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.</P
|
|
><P
|
|
>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.</P
|
|
></DIV
|
|
></DIV
|
|
><DIV
|
|
CLASS="SECTION"
|
|
><HR><H1
|
|
CLASS="SECTION"
|
|
><A
|
|
NAME="AEN187">2.2. How to NOT use Assembly</H1
|
|
><DIV
|
|
CLASS="SECTION"
|
|
><H2
|
|
CLASS="SECTION"
|
|
><A
|
|
NAME="AEN189">2.2.1. General procedure to achieve efficient code</H2
|
|
><P
|
|
>As says Charles Fiterman on
|
|
<A
|
|
HREF="news:comp.compilers"
|
|
TARGET="_top"
|
|
>comp.compilers</A
|
|
>
|
|
about human vs computer-generated assembly code:</P
|
|
><A
|
|
NAME="AEN193"><BLOCKQUOTE
|
|
CLASS="BLOCKQUOTE"
|
|
><P
|
|
CLASS="LITERALLAYOUT"
|
|
>The human should always win and here is why.<br>
|
|
<br>
|
|
First the human writes the whole thing in a high level language.<br>
|
|
Second he profiles it to find the hot spots where it spends its time.<br>
|
|
Third he has the compiler produce assembly for those small sections of code.<br>
|
|
Fourth he hand tunes them looking for tiny improvements over the machine generated code.<br>
|
|
<br>
|
|
The human wins because he can use the machine.</P
|
|
></BLOCKQUOTE
|
|
></DIV
|
|
><DIV
|
|
CLASS="SECTION"
|
|
><HR><H2
|
|
CLASS="SECTION"
|
|
><A
|
|
NAME="AEN195">2.2.2. Languages with optimizing compilers</H2
|
|
><P
|
|
>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!</P
|
|
><P
|
|
>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.</P
|
|
></DIV
|
|
><DIV
|
|
CLASS="SECTION"
|
|
><HR><H2
|
|
CLASS="SECTION"
|
|
><A
|
|
NAME="AEN199">2.2.3. General procedure to speed your code up</H2
|
|
><P
|
|
>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.</P
|
|
><P
|
|
>Hence, if you identify some code portion as being too slow, you should
|
|
|
|
<P
|
|
></P
|
|
><UL
|
|
><LI
|
|
><P
|
|
>first try to use a better algorithm;</P
|
|
></LI
|
|
><LI
|
|
><P
|
|
>then try to compile it rather than interpret it;</P
|
|
></LI
|
|
><LI
|
|
><P
|
|
>then try to enable and tweak optimization from your compiler;</P
|
|
></LI
|
|
><LI
|
|
><P
|
|
>then give the compiler hints about how to optimize
|
|
(typing information in LISP; register usage with GCC;
|
|
lots of options in most compilers, etc).</P
|
|
></LI
|
|
><LI
|
|
><P
|
|
>then possibly fallback to assembly programming</P
|
|
></LI
|
|
></UL
|
|
> </P
|
|
><P
|
|
>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.</P
|
|
></DIV
|
|
><DIV
|
|
CLASS="SECTION"
|
|
><HR><H2
|
|
CLASS="SECTION"
|
|
><A
|
|
NAME="AEN215">2.2.4. Inspecting compiler-generated code</H2
|
|
><P
|
|
>There are many reasons to inspect compiler-generated assembly code.
|
|
Here is what you'll do with such code:
|
|
|
|
<P
|
|
></P
|
|
><UL
|
|
><LI
|
|
><P
|
|
>check whether generated code
|
|
can be obviously enhanced with hand-coded assembly
|
|
(or by tweaking compiler switches)</P
|
|
></LI
|
|
><LI
|
|
><P
|
|
>when that's the case,
|
|
start from generated code and modify it
|
|
instead of starting from scratch</P
|
|
></LI
|
|
><LI
|
|
><P
|
|
>more generally, use generated code as stubs to modify,
|
|
which at least gets right the way
|
|
your assembly routines interface to the external world</P
|
|
></LI
|
|
><LI
|
|
><P
|
|
>track down bugs in your compiler (hopefully the rarer)</P
|
|
></LI
|
|
></UL
|
|
> </P
|
|
><P
|
|
>The standard way to have assembly code be generated
|
|
is to invoke your compiler with the <TT
|
|
CLASS="OPTION"
|
|
>-S</TT
|
|
> 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 <TT
|
|
CLASS="OPTION"
|
|
>-fverbose-asm</TT
|
|
> command-line option.
|
|
Of course, if you want to get good assembly code,
|
|
don't forget your usual optimization options and hints!</P
|
|
></DIV
|
|
></DIV
|
|
><DIV
|
|
CLASS="SECTION"
|
|
><HR><H1
|
|
CLASS="SECTION"
|
|
><A
|
|
NAME="AEN230">2.3. Linux and assembly</H1
|
|
><P
|
|
>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++.</P
|
|
><P
|
|
>You may <EM
|
|
>need</EM
|
|
> to use assembly, or you may <EM
|
|
>want</EM
|
|
> to use assembly.
|
|
In short, main practical (<EM
|
|
>need</EM
|
|
>) reasons
|
|
of diving into the assembly realm are <EM
|
|
>small code</EM
|
|
>
|
|
and <EM
|
|
><SPAN
|
|
CLASS="APPLICATION"
|
|
>libc</SPAN
|
|
> independence</EM
|
|
>.
|
|
Impractical (<EM
|
|
>want</EM
|
|
>), and the most often reason is
|
|
being just an old crazy hacker,
|
|
who has twenty years old habit of doing everything in assembly language.</P
|
|
><P
|
|
>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, <SPAN
|
|
CLASS="APPLICATION"
|
|
>libc</SPAN
|
|
>
|
|
and all that stuff of <SPAN
|
|
CLASS="APPLICATION"
|
|
>(file|find|text|sh|etc.) utils</SPAN
|
|
>
|
|
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 <B
|
|
CLASS="COMMAND"
|
|
>httpd</B
|
|
> 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.</P
|
|
></DIV
|
|
></DIV
|
|
><DIV
|
|
CLASS="CHAPTER"
|
|
><HR><H1
|
|
><A
|
|
NAME="S-ASSEM">Chapter 3. Assemblers</H1
|
|
><DIV
|
|
CLASS="SECTION"
|
|
><H1
|
|
CLASS="SECTION"
|
|
><A
|
|
NAME="P-GCC">3.1. GCC Inline Assembly</H1
|
|
><P
|
|
>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.</P
|
|
><DIV
|
|
CLASS="SECTION"
|
|
><HR><H2
|
|
CLASS="SECTION"
|
|
><A
|
|
NAME="AEN250">3.1.1. Where to find GCC</H2
|
|
><P
|
|
>The original GCC site is the GNU FTP site
|
|
<A
|
|
HREF="ftp://prep.ai.mit.edu/pub/gnu/gcc/"
|
|
TARGET="_top"
|
|
>ftp://prep.ai.mit.edu/pub/gnu/gcc/</A
|
|
>
|
|
together with all released application software from the GNU project.
|
|
Linux-configured and pre-compiled versions can be found in
|
|
<A
|
|
HREF="ftp://metalab.unc.edu/pub/Linux/GCC/"
|
|
TARGET="_top"
|
|
>ftp://metalab.unc.edu/pub/Linux/GCC/</A
|
|
>
|
|
There are a lot of FTP mirrors of both sites
|
|
everywhere around the world, as well as CD-ROM copies.</P
|
|
><P
|
|
>GCC development has split into two branches some time ago (GCC 2.8 and EGCS),
|
|
but they merged back, and current GCC webpage is
|
|
<A
|
|
HREF="http://gcc.gnu.org"
|
|
TARGET="_top"
|
|
>http://gcc.gnu.org</A
|
|
>.</P
|
|
><P
|
|
>Sources adapted to your favorite OS and pre-compiled binaries
|
|
should be found at your usual FTP sites.</P
|
|
><P
|
|
><A
|
|
NAME="P-DJGPP"
|
|
></A
|
|
>
|
|
DOS port of GCC is called
|
|
<A
|
|
HREF="http://www.delorie.com/djgpp/"
|
|
TARGET="_top"
|
|
>DJGPP</A
|
|
>.</P
|
|
><P
|
|
>There are two Win32 GCC ports:
|
|
<A
|
|
HREF="http://sourceware.cygnus.com/cygwin/"
|
|
TARGET="_top"
|
|
>cygwin</A
|
|
> and
|
|
<A
|
|
HREF="http://www.mingw.org"
|
|
TARGET="_top"
|
|
>mingw</A
|
|
> </P
|
|
><P
|
|
>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:
|
|
<A
|
|
HREF="ftp://ftp-os2.cdrom.com/pub/os2/emx09c/"
|
|
TARGET="_top"
|
|
>ftp://ftp-os2.cdrom.com/pub/os2/emx09c</A
|
|
>.</P
|
|
></DIV
|
|
><DIV
|
|
CLASS="SECTION"
|
|
><HR><H2
|
|
CLASS="SECTION"
|
|
><A
|
|
NAME="AEN266">3.1.2. Where to find docs for GCC Inline Asm</H2
|
|
><P
|
|
>The documentation of GCC includes documentation files in TeXinfo format.
|
|
You can compile them with TeX and print then result,
|
|
or convert them to <TT
|
|
CLASS="FILENAME"
|
|
>.info</TT
|
|
>, and browse them with emacs,
|
|
or convert them to <TT
|
|
CLASS="FILENAME"
|
|
>.html</TT
|
|
>, or nearly whatever you like;
|
|
convert (with the right tools) to whatever you like,
|
|
or just read as is. The <TT
|
|
CLASS="FILENAME"
|
|
>.info</TT
|
|
> files
|
|
are generally found on any good installation for GCC.</P
|
|
><P
|
|
>The right section to look for is <TT
|
|
CLASS="LITERAL"
|
|
>C Extensions::Extended Asm::</TT
|
|
></P
|
|
><P
|
|
>Section <TT
|
|
CLASS="LITERAL"
|
|
>Invoking GCC::Submodel Options::i386 Options::</TT
|
|
> might help too.
|
|
Particularly, it gives the i386 specific constraint names for registers:
|
|
<TT
|
|
CLASS="LITERAL"
|
|
>abcdSDB</TT
|
|
> correspond to
|
|
<TT
|
|
CLASS="LITERAL"
|
|
>%eax</TT
|
|
>,
|
|
<TT
|
|
CLASS="LITERAL"
|
|
>%ebx</TT
|
|
>,
|
|
<TT
|
|
CLASS="LITERAL"
|
|
>%ecx</TT
|
|
>,
|
|
<TT
|
|
CLASS="LITERAL"
|
|
>%edx</TT
|
|
>,
|
|
<TT
|
|
CLASS="LITERAL"
|
|
>%esi</TT
|
|
>,
|
|
<TT
|
|
CLASS="LITERAL"
|
|
>%edi</TT
|
|
>
|
|
and
|
|
<TT
|
|
CLASS="LITERAL"
|
|
>%ebp</TT
|
|
>
|
|
respectively (no letter for <TT
|
|
CLASS="LITERAL"
|
|
>%esp</TT
|
|
>).</P
|
|
><P
|
|
>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
|
|
<A
|
|
HREF="#P-DJGPP"
|
|
>DJGPP site</A
|
|
>,
|
|
that contains a mine of other useful information:
|
|
<A
|
|
HREF="http://www.delorie.com/djgpp/doc/brennan/"
|
|
TARGET="_top"
|
|
>http://www.delorie.com/djgpp/doc/brennan/</A
|
|
>, and in the
|
|
<A
|
|
HREF="http://www.castle.net/~avly/djasm.html"
|
|
TARGET="_top"
|
|
>DJGPP Quick ASM Programming Guide</A
|
|
>.</P
|
|
><P
|
|
>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.</P
|
|
><P
|
|
>Find <EM
|
|
>lots</EM
|
|
> of useful examples in the
|
|
<TT
|
|
CLASS="FILENAME"
|
|
>linux/include/asm-i386/</TT
|
|
>
|
|
subdirectory of the sources for the Linux kernel.</P
|
|
></DIV
|
|
><DIV
|
|
CLASS="SECTION"
|
|
><HR><H2
|
|
CLASS="SECTION"
|
|
><A
|
|
NAME="AEN293">3.1.3. Invoking GCC to build proper inline assembly code</H2
|
|
><P
|
|
>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 <TT
|
|
CLASS="FUNCTION"
|
|
>extern inline</TT
|
|
> functions,
|
|
GCC must be invoked with the <TT
|
|
CLASS="OPTION"
|
|
>-O</TT
|
|
> flag
|
|
(or <TT
|
|
CLASS="OPTION"
|
|
>-O2</TT
|
|
>, <TT
|
|
CLASS="OPTION"
|
|
>-O3</TT
|
|
>, 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 <TT
|
|
CLASS="FUNCTION"
|
|
>extern</TT
|
|
> 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.</P
|
|
><P
|
|
>Inline assembly can be disabled with <TT
|
|
CLASS="OPTION"
|
|
>-fno-asm</TT
|
|
>,
|
|
which will have the compiler die when using extended inline asm syntax,
|
|
or else generate calls to an external function named <TT
|
|
CLASS="FUNCTION"
|
|
>asm()</TT
|
|
>
|
|
that the linker can't resolve.
|
|
To counter such flag, <TT
|
|
CLASS="OPTION"
|
|
>-fasm</TT
|
|
> restores treatment
|
|
of the <TT
|
|
CLASS="LITERAL"
|
|
>asm</TT
|
|
> keyword.</P
|
|
><P
|
|
>More generally, good compile flags for GCC on the x86 platform are</P
|
|
><P
|
|
><B
|
|
CLASS="COMMAND"
|
|
>gcc -O2 -fomit-frame-pointer -W -Wall</B
|
|
></P
|
|
><P
|
|
><TT
|
|
CLASS="OPTION"
|
|
>-O2</TT
|
|
> 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 <TT
|
|
CLASS="OPTION"
|
|
>-O6</TT
|
|
>.</P
|
|
><P
|
|
><TT
|
|
CLASS="OPTION"
|
|
>-fomit-frame-pointer</TT
|
|
> 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 (<B
|
|
CLASS="COMMAND"
|
|
>gdb</B
|
|
>),
|
|
but when you use these, you just don't care about size and speed anymore anyway.</P
|
|
><P
|
|
><TT
|
|
CLASS="OPTION"
|
|
>-W -Wall</TT
|
|
> enables all useful warnings
|
|
and helps you to catch obvious stupid errors.</P
|
|
><P
|
|
>You can add some CPU-specific <TT
|
|
CLASS="OPTION"
|
|
>-m486</TT
|
|
> or such flag so that
|
|
GCC will produce code that is more adapted to your precise CPU.
|
|
Note that modern GCC has <TT
|
|
CLASS="OPTION"
|
|
>-mpentium</TT
|
|
> and such flags
|
|
(and <A
|
|
HREF="http://goof.com/pcg/"
|
|
TARGET="_top"
|
|
>PGCC</A
|
|
> 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.</P
|
|
><P
|
|
><TT
|
|
CLASS="OPTION"
|
|
>-m386</TT
|
|
> 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.</P
|
|
><P
|
|
>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.</P
|
|
><P
|
|
>To optimize even more, option <TT
|
|
CLASS="OPTION"
|
|
>-mregparm=2</TT
|
|
>
|
|
and/or corresponding function attribute might help,
|
|
but might pose lots of problems when linking to foreign code,
|
|
<EM
|
|
>including <SPAN
|
|
CLASS="APPLICATION"
|
|
>libc</SPAN
|
|
></EM
|
|
>.
|
|
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...</P
|
|
><P
|
|
>Note that you can add make these flags the default by editing file
|
|
<TT
|
|
CLASS="FILENAME"
|
|
>/usr/lib/gcc-lib/i486-linux/2.7.2.3/specs</TT
|
|
>
|
|
or wherever that is on your system
|
|
(better not add <TT
|
|
CLASS="OPTION"
|
|
>-W -Wall</TT
|
|
> there, though).
|
|
The exact location of the GCC specs files on system can be found by
|
|
<B
|
|
CLASS="COMMAND"
|
|
>gcc -v</B
|
|
>.</P
|
|
></DIV
|
|
><DIV
|
|
CLASS="SECTION"
|
|
><HR><H2
|
|
CLASS="SECTION"
|
|
><A
|
|
NAME="AEN332">3.1.4. Macro support</H2
|
|
><P
|
|
>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.</P
|
|
><P
|
|
>Thus, you can make 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 <TT
|
|
CLASS="LITERAL"
|
|
>1:</TT
|
|
> 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.</P
|
|
><P
|
|
>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.</P
|
|
></DIV
|
|
></DIV
|
|
><DIV
|
|
CLASS="SECTION"
|
|
><HR><H1
|
|
CLASS="SECTION"
|
|
><A
|
|
NAME="P-GAS">3.2. GAS</H1
|
|
><P
|
|
>GAS is the GNU Assembler, that GCC relies upon.</P
|
|
><DIV
|
|
CLASS="SECTION"
|
|
><HR><H2
|
|
CLASS="SECTION"
|
|
><A
|
|
NAME="AEN341">3.2.1. Where to find it</H2
|
|
><P
|
|
>Find it at the same place where you've found GCC,
|
|
in the binutils package.
|
|
The latest version of binutils is available from
|
|
<A
|
|
HREF="http://sources.redhat.com/binutils/"
|
|
TARGET="_top"
|
|
>http://sources.redhat.com/binutils/</A
|
|
>.</P
|
|
></DIV
|
|
><DIV
|
|
CLASS="SECTION"
|
|
><HR><H2
|
|
CLASS="SECTION"
|
|
><A
|
|
NAME="AEN345">3.2.2. What is this AT&T syntax</H2
|
|
><P
|
|
>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.</P
|
|
><P
|
|
>Here are the major caveats about GAS syntax:
|
|
|
|
<P
|
|
></P
|
|
><UL
|
|
><LI
|
|
><P
|
|
>Register names are prefixed with <TT
|
|
CLASS="LITERAL"
|
|
>%</TT
|
|
>, so that registers
|
|
are <TT
|
|
CLASS="LITERAL"
|
|
>%eax</TT
|
|
>, <TT
|
|
CLASS="LITERAL"
|
|
>%dl</TT
|
|
> and so on,
|
|
instead of just <TT
|
|
CLASS="LITERAL"
|
|
>eax</TT
|
|
>, <TT
|
|
CLASS="LITERAL"
|
|
>dl</TT
|
|
>, 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.</P
|
|
></LI
|
|
><LI
|
|
><P
|
|
>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
|
|
<TT
|
|
CLASS="FUNCTION"
|
|
>mov eax,edx</TT
|
|
>
|
|
(move contents of register <TT
|
|
CLASS="LITERAL"
|
|
>edx</TT
|
|
> into register <TT
|
|
CLASS="LITERAL"
|
|
>eax</TT
|
|
>)
|
|
will be in GAS syntax
|
|
<TT
|
|
CLASS="FUNCTION"
|
|
>mov %edx,%eax</TT
|
|
>.</P
|
|
></LI
|
|
><LI
|
|
><P
|
|
>The operand size is specified as a suffix to the instruction name.
|
|
The suffix is
|
|
<TT
|
|
CLASS="LITERAL"
|
|
>b</TT
|
|
> for (8-bit) byte,
|
|
<TT
|
|
CLASS="LITERAL"
|
|
>w</TT
|
|
> for (16-bit) word, and
|
|
<TT
|
|
CLASS="LITERAL"
|
|
>l</TT
|
|
> for (32-bit) long.
|
|
For instance, the correct syntax for the above instruction
|
|
would have been <TT
|
|
CLASS="FUNCTION"
|
|
>movl %edx,%eax</TT
|
|
>.
|
|
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).</P
|
|
></LI
|
|
><LI
|
|
><P
|
|
>Immediate operands are marked with a <TT
|
|
CLASS="LITERAL"
|
|
>$</TT
|
|
> prefix,
|
|
as in <TT
|
|
CLASS="FUNCTION"
|
|
>addl $5,%eax</TT
|
|
>
|
|
(add immediate long value 5 to register <TT
|
|
CLASS="LITERAL"
|
|
>%eax</TT
|
|
>).</P
|
|
></LI
|
|
><LI
|
|
><P
|
|
>Missing operand prefix indicates that it is memory-contents;
|
|
hence <TT
|
|
CLASS="FUNCTION"
|
|
>movl $foo,%eax</TT
|
|
>
|
|
puts the <EM
|
|
>address</EM
|
|
> of variable <TT
|
|
CLASS="LITERAL"
|
|
>foo</TT
|
|
>
|
|
into register <TT
|
|
CLASS="LITERAL"
|
|
>%eax</TT
|
|
>,
|
|
but <TT
|
|
CLASS="FUNCTION"
|
|
>movl foo,%eax</TT
|
|
>
|
|
puts the <EM
|
|
>contents</EM
|
|
> of variable <TT
|
|
CLASS="LITERAL"
|
|
>foo</TT
|
|
>
|
|
into register <TT
|
|
CLASS="LITERAL"
|
|
>%eax</TT
|
|
>.</P
|
|
></LI
|
|
><LI
|
|
><P
|
|
>Indexing or indirection is done by enclosing the index register
|
|
or indirection memory cell address in parentheses,
|
|
as in <TT
|
|
CLASS="FUNCTION"
|
|
>testb $0x80,17(%ebp)</TT
|
|
>
|
|
(test the high bit of the byte value at offset 17
|
|
from the cell pointed to by <TT
|
|
CLASS="LITERAL"
|
|
>%ebp</TT
|
|
>).</P
|
|
></LI
|
|
></UL
|
|
> </P
|
|
><P
|
|
><A
|
|
NAME="P-CONVERT"
|
|
></A
|
|
>
|
|
Note: There are <A
|
|
HREF="#S-RES"
|
|
>few programs</A
|
|
> 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.</P
|
|
><P
|
|
>GAS has comprehensive documentation in TeXinfo format,
|
|
which comes at least with the source distribution.
|
|
Browse extracted <TT
|
|
CLASS="FILENAME"
|
|
>.info</TT
|
|
> 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
|
|
<TT
|
|
CLASS="LITERAL"
|
|
>Machine Dependencies::i386-Dependent::</TT
|
|
></P
|
|
><P
|
|
>Again, the sources for Linux (the OS kernel) come in as excellent examples;
|
|
see under <TT
|
|
CLASS="FILENAME"
|
|
>linux/arch/i386/</TT
|
|
> the following files:
|
|
<TT
|
|
CLASS="FILENAME"
|
|
>kernel/*.S</TT
|
|
>,
|
|
<TT
|
|
CLASS="FILENAME"
|
|
>boot/compressed/*.S</TT
|
|
>,
|
|
<TT
|
|
CLASS="FILENAME"
|
|
>math-emu/*.S</TT
|
|
>.</P
|
|
><P
|
|
>If you are writing kind of a language, a thread package, etc.,
|
|
you might as well see how other languages (
|
|
<A
|
|
HREF="http://para.inria.fr/"
|
|
TARGET="_top"
|
|
>OCaml</A
|
|
>,
|
|
<A
|
|
HREF="http://www.jwdt.com/~paysan/gforth.html"
|
|
TARGET="_top"
|
|
>Gforth</A
|
|
>,
|
|
etc.),
|
|
or thread packages (QuickThreads, MIT pthreads, LinuxThreads, etc),
|
|
or whatever else do it.</P
|
|
><P
|
|
>Finally, just compiling a C program to assembly
|
|
might show you the syntax for the kind of instructions you want.
|
|
See section <A
|
|
HREF="#S-DOYOU"
|
|
>Do you need assembly?</A
|
|
> above.</P
|
|
></DIV
|
|
><DIV
|
|
CLASS="SECTION"
|
|
><HR><H2
|
|
CLASS="SECTION"
|
|
><A
|
|
NAME="AEN404">3.2.3. Intel syntax</H2
|
|
><P
|
|
>Good news are that starting from binutils 2.10 release,
|
|
GAS supports Intel syntax too.
|
|
It can be triggered with <TT
|
|
CLASS="LITERAL"
|
|
>.intel_syntax</TT
|
|
> directive.
|
|
Unfortunately this mode is not documented (yet?) in the official
|
|
binutils manual, so if you want to use it, try to examine
|
|
<A
|
|
HREF="http://home.snafu.de/phpr/lhpas86.html.gz"
|
|
TARGET="_top"
|
|
>http://home.snafu.de/phpr/lhpas86.html.gz</A
|
|
>,
|
|
which is an extract from AMD 64bit port of binutils 2.11.</P
|
|
></DIV
|
|
><DIV
|
|
CLASS="SECTION"
|
|
><HR><H2
|
|
CLASS="SECTION"
|
|
><A
|
|
NAME="AEN409">3.2.4. 16-bit mode</H2
|
|
><P
|
|
>Binutils (2.9.1.0.25+) now fully support 16-bit mode
|
|
(registers <EM
|
|
>and</EM
|
|
> addressing) on i386 PCs.
|
|
Use <TT
|
|
CLASS="LITERAL"
|
|
>.code16</TT
|
|
> and <TT
|
|
CLASS="LITERAL"
|
|
>.code32</TT
|
|
>
|
|
to switch between assembly modes.</P
|
|
><P
|
|
>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
|
|
<TT
|
|
CLASS="LITERAL"
|
|
>asm(".code16\n")</TT
|
|
>.
|
|
GCC will still emit only 32-bit addressing modes,
|
|
but GAS will insert proper 32-bit prefixes for them.</P
|
|
></DIV
|
|
><DIV
|
|
CLASS="SECTION"
|
|
><HR><H2
|
|
CLASS="SECTION"
|
|
><A
|
|
NAME="AEN417">3.2.5. Macro support</H2
|
|
><P
|
|
>GAS has some macro capability included, as detailed in the texinfo docs.
|
|
Moreover, while GCC recognizes <TT
|
|
CLASS="FILENAME"
|
|
>.s</TT
|
|
> files as raw assembly
|
|
to send to GAS, it also recognizes <TT
|
|
CLASS="FILENAME"
|
|
>.S</TT
|
|
> files as files
|
|
to pipe through CPP before feeding them to GAS.
|
|
Again and again, see Linux sources for examples.</P
|
|
><P
|
|
>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 <A
|
|
HREF="#P-CPP"
|
|
>CPP</A
|
|
> and <A
|
|
HREF="#P-M4"
|
|
>M4</A
|
|
>.
|
|
I have no idea on details, but it comes with its own texinfo documentation,
|
|
which you would like to browse (<B
|
|
CLASS="COMMAND"
|
|
>info gasp</B
|
|
>), print, grok.
|
|
GAS with GASP looks like a regular macro-assembler to me.</P
|
|
></DIV
|
|
></DIV
|
|
><DIV
|
|
CLASS="SECTION"
|
|
><HR><H1
|
|
CLASS="SECTION"
|
|
><A
|
|
NAME="P-NASM">3.3. NASM</H1
|
|
><P
|
|
>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.</P
|
|
><DIV
|
|
CLASS="SECTION"
|
|
><HR><H2
|
|
CLASS="SECTION"
|
|
><A
|
|
NAME="P-NASM-WHERE">3.3.1. Where to find NASM</H2
|
|
><P
|
|
><A
|
|
HREF="http://nasm.sourceforge.net"
|
|
TARGET="_top"
|
|
>http://nasm.sourceforge.net</A
|
|
>,
|
|
<A
|
|
HREF="http://www.cryogen.com/nasm/"
|
|
TARGET="_top"
|
|
>http://www.cryogen.com/nasm/</A
|
|
></P
|
|
><P
|
|
>Binary release on your usual metalab mirror
|
|
in <TT
|
|
CLASS="FILENAME"
|
|
>devel/lang/asm/</TT
|
|
> directory.
|
|
Should also be available as <TT
|
|
CLASS="FILENAME"
|
|
>.rpm</TT
|
|
> or
|
|
<TT
|
|
CLASS="FILENAME"
|
|
>.deb</TT
|
|
> in your usual RedHat/Debian distributions' contrib.</P
|
|
></DIV
|
|
><DIV
|
|
CLASS="SECTION"
|
|
><HR><H2
|
|
CLASS="SECTION"
|
|
><A
|
|
NAME="AEN438">3.3.2. What it does</H2
|
|
><P
|
|
>The syntax is Intel-style.
|
|
Comprehensive macroprocessing support is integrated.</P
|
|
><P
|
|
>Supported object file formats are
|
|
<TT
|
|
CLASS="LITERAL"
|
|
>bin</TT
|
|
>,
|
|
<TT
|
|
CLASS="LITERAL"
|
|
>aout</TT
|
|
>,
|
|
<TT
|
|
CLASS="LITERAL"
|
|
>coff</TT
|
|
>,
|
|
<TT
|
|
CLASS="LITERAL"
|
|
>elf</TT
|
|
>,
|
|
<TT
|
|
CLASS="LITERAL"
|
|
>as86</TT
|
|
>,
|
|
<TT
|
|
CLASS="LITERAL"
|
|
>obj</TT
|
|
> (DOS),
|
|
<TT
|
|
CLASS="LITERAL"
|
|
>win32</TT
|
|
>,
|
|
<TT
|
|
CLASS="LITERAL"
|
|
>rdf</TT
|
|
> (their own format).</P
|
|
><P
|
|
>NASM can be used as a backend for the free LCC compiler
|
|
(support files included).</P
|
|
><P
|
|
>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.</P
|
|
><DIV
|
|
CLASS="NOTE"
|
|
><P
|
|
></P
|
|
><TABLE
|
|
CLASS="NOTE"
|
|
WIDTH="100%"
|
|
BORDER="0"
|
|
><TR
|
|
><TD
|
|
WIDTH="25"
|
|
ALIGN="CENTER"
|
|
VALIGN="TOP"
|
|
><IMG
|
|
SRC="../images/note.gif"
|
|
HSPACE="5"
|
|
ALT="Note"></TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
><P
|
|
>NASM comes with a disassembler, NDISASM.</P
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></DIV
|
|
><P
|
|
>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..</P
|
|
><P
|
|
>Note: There are <A
|
|
HREF="#S-RES"
|
|
>few programs</A
|
|
>
|
|
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.</P
|
|
></DIV
|
|
></DIV
|
|
><DIV
|
|
CLASS="SECTION"
|
|
><HR><H1
|
|
CLASS="SECTION"
|
|
><A
|
|
NAME="P-AS86">3.4. AS86</H1
|
|
><P
|
|
>AS86 is a 80x86 assembler, both 16-bit and 32-bit,
|
|
with integrated macro support.
|
|
It has mostly Intel-syntax, though it differs slightly as for addressing modes.</P
|
|
><DIV
|
|
CLASS="SECTION"
|
|
><HR><H2
|
|
CLASS="SECTION"
|
|
><A
|
|
NAME="AEN460">3.4.1. Where to get AS86</H2
|
|
><P
|
|
>Current version is 0.16, it can be found at
|
|
<A
|
|
HREF="http://www.cix.co.uk/~mayday/"
|
|
TARGET="_top"
|
|
>http://www.cix.co.uk/~mayday/</A
|
|
>, in bin86 package with linker (ld86),
|
|
or as separate archive.</P
|
|
><DIV
|
|
CLASS="NOTE"
|
|
><P
|
|
></P
|
|
><TABLE
|
|
CLASS="NOTE"
|
|
WIDTH="100%"
|
|
BORDER="0"
|
|
><TR
|
|
><TD
|
|
WIDTH="25"
|
|
ALIGN="CENTER"
|
|
VALIGN="TOP"
|
|
><IMG
|
|
SRC="../images/note.gif"
|
|
HSPACE="5"
|
|
ALT="Note"></TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
><P
|
|
>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.</P
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></DIV
|
|
></DIV
|
|
><DIV
|
|
CLASS="SECTION"
|
|
><HR><H2
|
|
CLASS="SECTION"
|
|
><A
|
|
NAME="AEN466">3.4.2. Where to find docs</H2
|
|
><P
|
|
>See the man page and as.doc from the source package.
|
|
When in doubt, the sources themselves are often a good docs:
|
|
they aren't very well commented, but the programming style is straightforward.
|
|
You might try to see how as86 is used in ELKS, LILO, or Tunes 0.0.0.25...</P
|
|
></DIV
|
|
><DIV
|
|
CLASS="SECTION"
|
|
><HR><H2
|
|
CLASS="SECTION"
|
|
><A
|
|
NAME="AEN469">3.4.3. Using AS86 with BCC</H2
|
|
><P
|
|
>Here's the GNU Makefile entry for using BCC
|
|
to transform <TT
|
|
CLASS="FILENAME"
|
|
>.s</TT
|
|
> asm
|
|
into both a.out <TT
|
|
CLASS="FILENAME"
|
|
>.o</TT
|
|
> object
|
|
and <TT
|
|
CLASS="FILENAME"
|
|
>.l</TT
|
|
> listing:</P
|
|
><P
|
|
><TABLE
|
|
BORDER="0"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="PROGRAMLISTING"
|
|
>%.o %.l: %.s
|
|
bcc -3 -G -c -A-d -A-l -A$*.l -o $*.o $<</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></P
|
|
><P
|
|
>Remove the <TT
|
|
CLASS="LITERAL"
|
|
>%.l</TT
|
|
>,
|
|
<TT
|
|
CLASS="LITERAL"
|
|
>-A-l</TT
|
|
>, and <TT
|
|
CLASS="LITERAL"
|
|
>-A$*.l</TT
|
|
>,
|
|
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.</P
|
|
></DIV
|
|
></DIV
|
|
><DIV
|
|
CLASS="SECTION"
|
|
><HR><H1
|
|
CLASS="SECTION"
|
|
><A
|
|
NAME="P-OTHER">3.5. Other Assemblers</H1
|
|
><P
|
|
>There are other assemblers with various interesting and outstanding features
|
|
which may be of your interest as well.</P
|
|
><DIV
|
|
CLASS="NOTE"
|
|
><P
|
|
></P
|
|
><TABLE
|
|
CLASS="NOTE"
|
|
WIDTH="100%"
|
|
BORDER="0"
|
|
><TR
|
|
><TD
|
|
WIDTH="25"
|
|
ALIGN="CENTER"
|
|
VALIGN="TOP"
|
|
><IMG
|
|
SRC="../images/note.gif"
|
|
HSPACE="5"
|
|
ALT="Note"></TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
><P
|
|
>They can be in various stages of development,
|
|
and can be non-classic/high-level/whatever else.</P
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></DIV
|
|
><DIV
|
|
CLASS="SECTION"
|
|
><HR><H2
|
|
CLASS="SECTION"
|
|
><A
|
|
NAME="AEN486">3.5.1. YASM</H2
|
|
><P
|
|
>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.</P
|
|
><P
|
|
>It looks promising; it is under heavy development,
|
|
and you may want to take part.
|
|
See <A
|
|
HREF="http://www.tortall.net/projects/yasm/"
|
|
TARGET="_top"
|
|
>http://www.tortall.net/projects/yasm/</A
|
|
>.</P
|
|
></DIV
|
|
><DIV
|
|
CLASS="SECTION"
|
|
><HR><H2
|
|
CLASS="SECTION"
|
|
><A
|
|
NAME="AEN491">3.5.2. FASM</H2
|
|
><P
|
|
>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 and COFF output.
|
|
See <A
|
|
HREF="http://fasm.sourceforge.net"
|
|
TARGET="_top"
|
|
>http://fasm.sourceforge.net</A
|
|
>.</P
|
|
></DIV
|
|
><DIV
|
|
CLASS="SECTION"
|
|
><HR><H2
|
|
CLASS="SECTION"
|
|
><A
|
|
NAME="AEN495">3.5.3. OSIMPA (SHASM)</H2
|
|
><P
|
|
>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.</P
|
|
><P
|
|
>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:
|
|
<A
|
|
HREF="ftp://linux01.gwdg.de/pub/cLIeNUX/interim/"
|
|
TARGET="_top"
|
|
>ftp://linux01.gwdg.de/pub/cLIeNUX/interim/</A
|
|
>.
|
|
Probably you'll not use it on regular basis,
|
|
but at least it deserves your interest as an interesting idea.</P
|
|
></DIV
|
|
><DIV
|
|
CLASS="SECTION"
|
|
><HR><H2
|
|
CLASS="SECTION"
|
|
><A
|
|
NAME="AEN500">3.5.4. TDASM</H2
|
|
><P
|
|
>The Table Driven Assembler (TDASM) is a <EM
|
|
>free</EM
|
|
> 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.</P
|
|
><P
|
|
>It is available from <A
|
|
HREF="http://www.penguin.cz/~niki/tdasm/"
|
|
TARGET="_top"
|
|
>http://www.penguin.cz/~niki/tdasm/</A
|
|
>.</P
|
|
></DIV
|
|
><DIV
|
|
CLASS="SECTION"
|
|
><HR><H2
|
|
CLASS="SECTION"
|
|
><A
|
|
NAME="AEN506">3.5.5. HLA</H2
|
|
><P
|
|
><A
|
|
HREF="http://webster.cs.ucr.edu"
|
|
TARGET="_top"
|
|
>HLA</A
|
|
> is a
|
|
<EM
|
|
>H</EM
|
|
>igh
|
|
<EM
|
|
>L</EM
|
|
>evel
|
|
<EM
|
|
>A</EM
|
|
>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.</P
|
|
><P
|
|
>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.</P
|
|
></DIV
|
|
><DIV
|
|
CLASS="SECTION"
|
|
><HR><H2
|
|
CLASS="SECTION"
|
|
><A
|
|
NAME="AEN514">3.5.6. TALC</H2
|
|
><P
|
|
><A
|
|
HREF="http://www.cs.cornell.edu/talc/"
|
|
TARGET="_top"
|
|
>TALC</A
|
|
>
|
|
is another free MASM/Win32 based compiler
|
|
(however it supports ELF output, does it?).</P
|
|
><P
|
|
>TAL stands for
|
|
<EM
|
|
>T</EM
|
|
>yped
|
|
<EM
|
|
>A</EM
|
|
>ssembly
|
|
<EM
|
|
>L</EM
|
|
>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.</P
|
|
></DIV
|
|
><DIV
|
|
CLASS="SECTION"
|
|
><HR><H2
|
|
CLASS="SECTION"
|
|
><A
|
|
NAME="AEN522">3.5.7. Free Pascal</H2
|
|
><P
|
|
><A
|
|
HREF="http://www.freepascal.org"
|
|
TARGET="_top"
|
|
>Free Pascal</A
|
|
>
|
|
has an internal 32-bit assembler (based on NASM tables)
|
|
and a switchable output that allows:
|
|
<P
|
|
></P
|
|
><UL
|
|
><LI
|
|
><P
|
|
>Binary (ELF and coff when crosscompiled .o) output</P
|
|
></LI
|
|
><LI
|
|
><P
|
|
>NASM</P
|
|
></LI
|
|
><LI
|
|
><P
|
|
>MASM</P
|
|
></LI
|
|
><LI
|
|
><P
|
|
>TASM</P
|
|
></LI
|
|
><LI
|
|
><P
|
|
>AS (aout,coff, elf32)</P
|
|
></LI
|
|
></UL
|
|
></P
|
|
><P
|
|
>The MASM and TASM output are not as good debugged as the other two,
|
|
but can be handy sometimes.</P
|
|
><P
|
|
>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++).</P
|
|
><P
|
|
>Using a dummy RTL, one can even generate pure assembler programs.</P
|
|
></DIV
|
|
><DIV
|
|
CLASS="SECTION"
|
|
><HR><H2
|
|
CLASS="SECTION"
|
|
><A
|
|
NAME="AEN540">3.5.8. Win32Forth assembler</H2
|
|
><P
|
|
>Win32Forth is a <EM
|
|
>free</EM
|
|
> 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 <TT
|
|
CLASS="FILENAME"
|
|
>.obj</TT
|
|
> file,
|
|
but you could add that feature yourself, of course).
|
|
Find it at
|
|
<A
|
|
HREF="ftp://ftp.forth.org/pub/Forth/Compilers/native/windows/Win32For/"
|
|
TARGET="_top"
|
|
>ftp://ftp.forth.org/pub/Forth/Compilers/native/windows/Win32For/</A
|
|
>.</P
|
|
></DIV
|
|
><DIV
|
|
CLASS="SECTION"
|
|
><HR><H2
|
|
CLASS="SECTION"
|
|
><A
|
|
NAME="AEN546">3.5.9. Terse</H2
|
|
><P
|
|
><A
|
|
HREF="http://www.terse.com"
|
|
TARGET="_top"
|
|
>Terse</A
|
|
>
|
|
is a programming tool that provides <EM
|
|
>THE</EM
|
|
> 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.</P
|
|
><P
|
|
>As an interesting historic remark, on
|
|
<A
|
|
HREF="news:comp.compilers"
|
|
TARGET="_top"
|
|
>comp.compilers</A
|
|
>,</P
|
|
><P
|
|
><P
|
|
CLASS="LITERALLAYOUT"
|
|
>1999/07/11 19:36:51, the moderator wrote:<br>
|
|
<br>
|
|
"There's no reason that assemblers have to have awful syntax. About<br>
|
|
30 years ago I used Niklaus Wirth's PL360, which was basically a S/360<br>
|
|
assembler with Algol syntax and a a little syntactic sugar like while<br>
|
|
loops that turned into the obvious branches. It really was an<br>
|
|
assembler, e.g., you had to write out your expressions with explicit<br>
|
|
assignments of values to registers, but it was nice. Wirth used it to<br>
|
|
write Algol W, a small fast Algol subset, which was a predecessor to<br>
|
|
Pascal. As is so often the case, Algol W was a significant<br>
|
|
improvement over many of its successors. -John"</P
|
|
></P
|
|
></DIV
|
|
><DIV
|
|
CLASS="SECTION"
|
|
><HR><H2
|
|
CLASS="SECTION"
|
|
><A
|
|
NAME="AEN555">3.5.10. Non-free and/or Non-32bit x86 assemblers</H2
|
|
><P
|
|
>You may find more about them,
|
|
together with the basics of x86 assembly programming, in the
|
|
<A
|
|
HREF="#S-RES-GEN"
|
|
>Raymond Moon's x86 assembly FAQ</A
|
|
>.</P
|
|
><P
|
|
>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.</P
|
|
></DIV
|
|
></DIV
|
|
></DIV
|
|
><DIV
|
|
CLASS="CHAPTER"
|
|
><HR><H1
|
|
><A
|
|
NAME="S-META">Chapter 4. Metaprogramming</H1
|
|
><P
|
|
>Assembly programming is a bore,
|
|
but for critical parts of programs.</P
|
|
><P
|
|
>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.</P
|
|
><P
|
|
>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.</P
|
|
><DIV
|
|
CLASS="SECTION"
|
|
><HR><H1
|
|
CLASS="SECTION"
|
|
><A
|
|
NAME="AEN565">4.1. External filters</H1
|
|
><P
|
|
>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:</P
|
|
><P
|
|
> <TABLE
|
|
BORDER="0"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="PROGRAMLISTING"
|
|
>%.s: %.S other_dependencies
|
|
$(FILTER) $(FILTER_OPTIONS) < $< > $@</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
> </P
|
|
><DIV
|
|
CLASS="SECTION"
|
|
><HR><H2
|
|
CLASS="SECTION"
|
|
><A
|
|
NAME="P-CPP">4.1.1. CPP</H2
|
|
><P
|
|
>CPP is truly not very expressive, but it's enough for easy things,
|
|
it's standard, and called transparently by GCC.</P
|
|
><P
|
|
>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.</P
|
|
><P
|
|
>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.</P
|
|
></DIV
|
|
><DIV
|
|
CLASS="SECTION"
|
|
><HR><H2
|
|
CLASS="SECTION"
|
|
><A
|
|
NAME="P-M4">4.1.2. M4</H2
|
|
><P
|
|
>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.</P
|
|
><P
|
|
>See
|
|
<A
|
|
HREF="ftp://ftp.forth.org/pub/Forth/Compilers/native/unix/this4th.tar.gz"
|
|
TARGET="_top"
|
|
>macro4th (this4th)</A
|
|
> or
|
|
<A
|
|
HREF="ftp://ftp.tunes.org/pub/tunes/obsolete/dist/tunes.0.0.0/tunes.0.0.0.25.src.zip"
|
|
TARGET="_top"
|
|
>the Tunes 0.0.0.25 sources</A
|
|
>
|
|
as examples of advanced macroprogramming using m4.</P
|
|
><P
|
|
>However, its disfunctional quoting and unquoting semantics force you to use
|
|
explicit continuation-passing tail-recursive macro style if
|
|
you want to do <EM
|
|
>advanced</EM
|
|
> 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.</P
|
|
><P
|
|
>The right version of M4 to get is <TT
|
|
CLASS="LITERAL"
|
|
>GNU m4 1.4</TT
|
|
>
|
|
(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?).</P
|
|
></DIV
|
|
><DIV
|
|
CLASS="SECTION"
|
|
><HR><H2
|
|
CLASS="SECTION"
|
|
><A
|
|
NAME="AEN585">4.1.3. Macroprocessing with your own filter</H2
|
|
><P
|
|
>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".</P
|
|
></DIV
|
|
></DIV
|
|
><DIV
|
|
CLASS="SECTION"
|
|
><HR><H1
|
|
CLASS="SECTION"
|
|
><A
|
|
NAME="AEN588">4.2. Metaprogramming</H1
|
|
><P
|
|
>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.</P
|
|
><P
|
|
>For instance, you could use a program outputting source code
|
|
|
|
<P
|
|
></P
|
|
><UL
|
|
><LI
|
|
><P
|
|
>to generate sine/cosine/whatever lookup tables,</P
|
|
></LI
|
|
><LI
|
|
><P
|
|
>to extract a source-form representation of a binary file,</P
|
|
></LI
|
|
><LI
|
|
><P
|
|
>to compile your bitmaps into fast display routines,</P
|
|
></LI
|
|
><LI
|
|
><P
|
|
>to extract documentation, initialization/finalization code,
|
|
description tables, as well as normal code from the same source files,</P
|
|
></LI
|
|
><LI
|
|
><P
|
|
>to have customized assembly code, generated from a perl/shell/scheme script
|
|
that does arbitrary processing,</P
|
|
></LI
|
|
><LI
|
|
><P
|
|
>to propagate data defined at one point only
|
|
into several cross-referencing tables and code chunks.</P
|
|
></LI
|
|
><LI
|
|
><P
|
|
>etc.</P
|
|
></LI
|
|
></UL
|
|
> </P
|
|
><P
|
|
>Think about it!</P
|
|
><DIV
|
|
CLASS="SECTION"
|
|
><HR><H2
|
|
CLASS="SECTION"
|
|
><A
|
|
NAME="AEN608">4.2.1. Backends from compilers</H2
|
|
><P
|
|
>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!</P
|
|
></DIV
|
|
><DIV
|
|
CLASS="SECTION"
|
|
><HR><H2
|
|
CLASS="SECTION"
|
|
><A
|
|
NAME="AEN611">4.2.2. The New-Jersey Machine-Code Toolkit</H2
|
|
><P
|
|
>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
|
|
<A
|
|
HREF="http://www.eecs.harvard.edu/~nr/toolkit/"
|
|
TARGET="_top"
|
|
>http://www.eecs.harvard.edu/~nr/toolkit/</A
|
|
></P
|
|
></DIV
|
|
><DIV
|
|
CLASS="SECTION"
|
|
><HR><H2
|
|
CLASS="SECTION"
|
|
><A
|
|
NAME="AEN615">4.2.3. TUNES</H2
|
|
><P
|
|
>The <A
|
|
HREF="http://www.tunes.org"
|
|
TARGET="_top"
|
|
>TUNES Project</A
|
|
>
|
|
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.</P
|
|
><P
|
|
>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.</P
|
|
></DIV
|
|
></DIV
|
|
></DIV
|
|
><DIV
|
|
CLASS="CHAPTER"
|
|
><HR><H1
|
|
><A
|
|
NAME="S-CALL">Chapter 5. Calling conventions</H1
|
|
><DIV
|
|
CLASS="SECTION"
|
|
><H1
|
|
CLASS="SECTION"
|
|
><A
|
|
NAME="AEN622">5.1. Linux</H1
|
|
><DIV
|
|
CLASS="SECTION"
|
|
><H2
|
|
CLASS="SECTION"
|
|
><A
|
|
NAME="AEN624">5.1.1. Linking to GCC</H2
|
|
><P
|
|
>This is the preferred way if you are developing mixed C-asm project.
|
|
Check GCC docs and examples from Linux kernel <TT
|
|
CLASS="FILENAME"
|
|
>.S</TT
|
|
> files
|
|
that go through <SPAN
|
|
CLASS="APPLICATION"
|
|
>gas</SPAN
|
|
>
|
|
(not those that go through <SPAN
|
|
CLASS="APPLICATION"
|
|
>as86</SPAN
|
|
>).</P
|
|
><P
|
|
>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.
|
|
<TT
|
|
CLASS="LITERAL"
|
|
>%ebp</TT
|
|
>,
|
|
<TT
|
|
CLASS="LITERAL"
|
|
>%esi</TT
|
|
>,
|
|
<TT
|
|
CLASS="LITERAL"
|
|
>%edi</TT
|
|
>,
|
|
<TT
|
|
CLASS="LITERAL"
|
|
>%ebx</TT
|
|
>
|
|
are callee-saved, other registers are caller-saved;
|
|
<TT
|
|
CLASS="LITERAL"
|
|
>%eax</TT
|
|
> is to hold the result, or
|
|
<TT
|
|
CLASS="LITERAL"
|
|
>%edx:%eax</TT
|
|
> for 64-bit results.</P
|
|
><P
|
|
>FP stack: I'm not sure, but I think result is in
|
|
<TT
|
|
CLASS="LITERAL"
|
|
>st(0)</TT
|
|
>, whole stack caller-saved.
|
|
The SVR4 i386 ABI specs at
|
|
<A
|
|
HREF="http://www.caldera.com/developer/devspecs/"
|
|
TARGET="_top"
|
|
>http://www.caldera.com/developer/devspecs/</A
|
|
>
|
|
is a good reference point if you want more details.</P
|
|
><P
|
|
>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 <TT
|
|
CLASS="FILENAME"
|
|
>.info</TT
|
|
> pages.</P
|
|
><P
|
|
>Beware that you must then declare the <TT
|
|
CLASS="LITERAL"
|
|
>cdecl</TT
|
|
> or
|
|
<TT
|
|
CLASS="LITERAL"
|
|
>regparm(0)</TT
|
|
>
|
|
attribute for a function that will follow standard GCC calling conventions.
|
|
See <TT
|
|
CLASS="LITERAL"
|
|
>C Extensions::Extended Asm::</TT
|
|
> section
|
|
from the GCC info pages.
|
|
See also how Linux defines its <TT
|
|
CLASS="LITERAL"
|
|
>asmlinkage</TT
|
|
> macro...</P
|
|
></DIV
|
|
><DIV
|
|
CLASS="SECTION"
|
|
><HR><H2
|
|
CLASS="SECTION"
|
|
><A
|
|
NAME="AEN647">5.1.2. ELF vs a.out problems</H2
|
|
><P
|
|
>Some C compilers prepend an underscore before every symbol,
|
|
while others do not.</P
|
|
><P
|
|
>Particularly, Linux a.out GCC does such prepending,
|
|
while Linux ELF GCC does not.</P
|
|
><P
|
|
>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...</P
|
|
><P
|
|
>You can also override the implicit C->asm renaming
|
|
by inserting statements like
|
|
|
|
<TABLE
|
|
BORDER="0"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="PROGRAMLISTING"
|
|
> void foo asm("bar") (void);</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
>
|
|
|
|
to be sure that the C function <TT
|
|
CLASS="FUNCTION"
|
|
>foo()</TT
|
|
>
|
|
will be called really <TT
|
|
CLASS="FUNCTION"
|
|
>bar</TT
|
|
> in assembly.</P
|
|
><P
|
|
>Note that the <B
|
|
CLASS="COMMAND"
|
|
>objcopy</B
|
|
> 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.</P
|
|
></DIV
|
|
><DIV
|
|
CLASS="SECTION"
|
|
><HR><H2
|
|
CLASS="SECTION"
|
|
><A
|
|
NAME="AEN658">5.1.3. Direct Linux syscalls</H2
|
|
><P
|
|
>Often you will be told that using
|
|
<SPAN
|
|
CLASS="APPLICATION"
|
|
>C library</SPAN
|
|
> (<SPAN
|
|
CLASS="ACRONYM"
|
|
>libc</SPAN
|
|
>)
|
|
is the only way, and direct system calls are bad.
|
|
This is true. To some extent.
|
|
In general, you must know that <SPAN
|
|
CLASS="APPLICATION"
|
|
>libc</SPAN
|
|
> is not sacred,
|
|
and in <EM
|
|
>most</EM
|
|
> 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 <SPAN
|
|
CLASS="APPLICATION"
|
|
>libc</SPAN
|
|
> in assembly programming
|
|
is more a question of taste/belief than something practical.
|
|
Remember, Linux is aiming to be POSIX compliant,
|
|
so does <SPAN
|
|
CLASS="APPLICATION"
|
|
>libc</SPAN
|
|
>.
|
|
This means that syntax of almost all
|
|
<SPAN
|
|
CLASS="APPLICATION"
|
|
>libc</SPAN
|
|
> "system calls"
|
|
exactly matches syntax of real kernel system calls (and vice versa).
|
|
Besides,
|
|
<SPAN
|
|
CLASS="APPLICATION"
|
|
>GNU libc</SPAN
|
|
>(<SPAN
|
|
CLASS="APPLICATION"
|
|
>glibc</SPAN
|
|
>)
|
|
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.
|
|
But.. main drawback of throwing <SPAN
|
|
CLASS="APPLICATION"
|
|
>libc</SPAN
|
|
> away
|
|
is that possibly you will need to implement several
|
|
<SPAN
|
|
CLASS="APPLICATION"
|
|
>libc</SPAN
|
|
> specific functions (that are not just syscall wrappers)
|
|
on your own (<TT
|
|
CLASS="FUNCTION"
|
|
>printf()</TT
|
|
> and Co.)..
|
|
and you are ready for that, aren't you? :)</P
|
|
><P
|
|
>Here is summary of direct system calls pros and cons.</P
|
|
><P
|
|
>Pros:
|
|
|
|
<P
|
|
></P
|
|
><UL
|
|
><LI
|
|
><P
|
|
>the smallest possible size; squeezing the last byte out of the system</P
|
|
></LI
|
|
><LI
|
|
><P
|
|
>the highest possible speed; squeezing cycles out of your favorite benchmark</P
|
|
></LI
|
|
><LI
|
|
><P
|
|
>full control: you can adapt your program/library
|
|
to your specific language or memory requirements or whatever</P
|
|
></LI
|
|
><LI
|
|
><P
|
|
>no pollution by libc cruft</P
|
|
></LI
|
|
><LI
|
|
><P
|
|
>no pollution by C calling conventions
|
|
(if you're developing your own language or environment)</P
|
|
></LI
|
|
><LI
|
|
><P
|
|
>static binaries make you independent from libc upgrades or crashes,
|
|
or from dangling <TT
|
|
CLASS="LITERAL"
|
|
>#!</TT
|
|
> path to an interpreter
|
|
(and are faster)</P
|
|
></LI
|
|
><LI
|
|
><P
|
|
>just for the fun out of it
|
|
(don't you get a kick out of assembly programming?)</P
|
|
></LI
|
|
></UL
|
|
> </P
|
|
><P
|
|
>Cons:
|
|
|
|
<P
|
|
></P
|
|
><UL
|
|
><LI
|
|
><P
|
|
>If any other program on your computer uses the libc,
|
|
then duplicating the libc code will actually
|
|
wastes memory, not saves it.</P
|
|
></LI
|
|
><LI
|
|
><P
|
|
>Services redundantly implemented in many static binaries
|
|
are a waste of memory.
|
|
But you can make your libc replacement a shared library.</P
|
|
></LI
|
|
><LI
|
|
><P
|
|
>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
|
|
<TT
|
|
CLASS="LITERAL"
|
|
>#!</TT
|
|
> 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
|
|
<A
|
|
HREF="http://language.perl.com/ppt/"
|
|
TARGET="_top"
|
|
>Perl PowerTools</A
|
|
>
|
|
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 <TT
|
|
CLASS="PARAMETER"
|
|
><I
|
|
>argv[0]</I
|
|
></TT
|
|
>;
|
|
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!</P
|
|
></LI
|
|
><LI
|
|
><P
|
|
>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.</P
|
|
></LI
|
|
><LI
|
|
><P
|
|
>Therefore, you might have to reimplement large parts of libc, from
|
|
<TT
|
|
CLASS="FUNCTION"
|
|
>printf()</TT
|
|
> to
|
|
<TT
|
|
CLASS="FUNCTION"
|
|
>malloc()</TT
|
|
> and
|
|
<TT
|
|
CLASS="FUNCTION"
|
|
>gethostbyname</TT
|
|
>.
|
|
It's redundant with the libc effort,
|
|
and can be <EM
|
|
>quite</EM
|
|
> 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 <A
|
|
HREF="ftp://linux01.gwdg.de/pub/cLIeNUX/interim/libsys.tgz"
|
|
TARGET="_top"
|
|
>libsys</A
|
|
>,
|
|
Felix von Leitner's <A
|
|
HREF="http://www.fefe.de/dietlibc/"
|
|
TARGET="_top"
|
|
>dietlibc</A
|
|
>,
|
|
Christian Fowelin's <A
|
|
HREF="http://www.fowelin.de/christian/computer/libASM/"
|
|
TARGET="_top"
|
|
>libASM</A
|
|
>,
|
|
<A
|
|
HREF="http://linuxassembly.org/asmutils.html"
|
|
TARGET="_top"
|
|
>asmutils</A
|
|
>
|
|
project is working on pure assembly libc)</P
|
|
></LI
|
|
><LI
|
|
><P
|
|
>Static libraries prevent you to benefit from libc upgrades as well as from
|
|
libc add-ons such as the <SPAN
|
|
CLASS="APPLICATION"
|
|
>zlibc</SPAN
|
|
> package,
|
|
that does on-the-fly transparent decompression
|
|
of gzip-compressed files.</P
|
|
></LI
|
|
><LI
|
|
><P
|
|
>The few instructions added by the libc can be
|
|
a <EM
|
|
>ridiculously</EM
|
|
> 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.</P
|
|
></LI
|
|
><LI
|
|
><P
|
|
>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).</P
|
|
></LI
|
|
><LI
|
|
><P
|
|
>See previous discussion for general speed optimization issue.</P
|
|
></LI
|
|
><LI
|
|
><P
|
|
>If syscalls are too slow to you,
|
|
you might want to hack the kernel sources (in C)
|
|
instead of staying in userland.</P
|
|
></LI
|
|
></UL
|
|
> </P
|
|
><P
|
|
>If you've pondered the above pros and cons,
|
|
and still want to use direct syscalls,
|
|
then here is some advice.</P
|
|
><P
|
|
> <P
|
|
></P
|
|
><UL
|
|
><LI
|
|
><P
|
|
>You can easily define your system calling functions
|
|
in a portable way in C (as opposed to unportable using assembly),
|
|
by including <TT
|
|
CLASS="FILENAME"
|
|
>asm/unistd.h</TT
|
|
>,
|
|
and using provided macros.</P
|
|
></LI
|
|
><LI
|
|
><P
|
|
>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!)</P
|
|
></LI
|
|
><LI
|
|
><P
|
|
>As an example of pure assembly code that does everything you want,
|
|
examine <A
|
|
HREF="#S-RES"
|
|
>Linux assembly resources</A
|
|
>.</P
|
|
></LI
|
|
></UL
|
|
> </P
|
|
><P
|
|
>Basically, you issue an <TT
|
|
CLASS="FUNCTION"
|
|
>int 0x80</TT
|
|
>, with the
|
|
<TT
|
|
CLASS="LITERAL"
|
|
>__NR_</TT
|
|
>syscallname number
|
|
(from <TT
|
|
CLASS="FILENAME"
|
|
>asm/unistd.h</TT
|
|
>) in <TT
|
|
CLASS="LITERAL"
|
|
>eax</TT
|
|
>,
|
|
and parameters (up to <A
|
|
HREF="#SIX-ARG"
|
|
>six</A
|
|
>) in
|
|
<TT
|
|
CLASS="LITERAL"
|
|
>ebx</TT
|
|
>,
|
|
<TT
|
|
CLASS="LITERAL"
|
|
>ecx</TT
|
|
>,
|
|
<TT
|
|
CLASS="LITERAL"
|
|
>edx</TT
|
|
>,
|
|
<TT
|
|
CLASS="LITERAL"
|
|
>esi</TT
|
|
>,
|
|
<TT
|
|
CLASS="LITERAL"
|
|
>edi</TT
|
|
>,
|
|
<A
|
|
HREF="#SIX-ARG"
|
|
><TT
|
|
CLASS="LITERAL"
|
|
>ebp</TT
|
|
></A
|
|
> respectively.</P
|
|
><P
|
|
>Result is returned in <TT
|
|
CLASS="LITERAL"
|
|
>eax</TT
|
|
>,
|
|
with a negative result being an error,
|
|
whose opposite is what libc would put into <TT
|
|
CLASS="LITERAL"
|
|
>errno</TT
|
|
>.
|
|
The user-stack is not touched,
|
|
so you needn't have a valid one when doing a syscall.</P
|
|
><DIV
|
|
CLASS="NOTE"
|
|
><P
|
|
></P
|
|
><TABLE
|
|
CLASS="NOTE"
|
|
WIDTH="100%"
|
|
BORDER="0"
|
|
><TR
|
|
><TD
|
|
WIDTH="25"
|
|
ALIGN="CENTER"
|
|
VALIGN="TOP"
|
|
><IMG
|
|
SRC="../images/note.gif"
|
|
HSPACE="5"
|
|
ALT="Note"></TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
><P
|
|
><A
|
|
NAME="SIX-ARG"
|
|
></A
|
|
>
|
|
Passing sixth parameter in <TT
|
|
CLASS="LITERAL"
|
|
>ebp</TT
|
|
>
|
|
appeared in Linux 2.4, previous Linux versions understand
|
|
only 5 parameters in registers.</P
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></DIV
|
|
><P
|
|
><A
|
|
HREF="http://www.linuxdoc.org/LDP/lki/"
|
|
TARGET="_top"
|
|
>Linux Kernel Internals</A
|
|
>,
|
|
and especially
|
|
<A
|
|
HREF="http://www.linuxdoc.org/LDP/lki/lki-2.html#ss2.11"
|
|
TARGET="_top"
|
|
>How System Calls Are Implemented on i386 Architecture?</A
|
|
>
|
|
chapter will give you more robust overview.</P
|
|
><P
|
|
>As for the invocation arguments passed to a process upon startup,
|
|
the general principle is that the stack
|
|
originally contains the number of arguments <TT
|
|
CLASS="PARAMETER"
|
|
><I
|
|
>argc</I
|
|
></TT
|
|
>,
|
|
then the list of pointers that constitute <TT
|
|
CLASS="PARAMETER"
|
|
><I
|
|
>*argv</I
|
|
></TT
|
|
>,
|
|
then a null-terminated sequence of null-terminated
|
|
<TT
|
|
CLASS="LITERAL"
|
|
>variable=value</TT
|
|
> strings for the
|
|
<TT
|
|
CLASS="PARAMETER"
|
|
><I
|
|
>environ</I
|
|
></TT
|
|
>ment.
|
|
For more details,
|
|
do examine <A
|
|
HREF="#S-RES"
|
|
>Linux assembly resources</A
|
|
>,
|
|
read the sources of C startup code from your libc
|
|
(<TT
|
|
CLASS="FILENAME"
|
|
>crt0.S</TT
|
|
> or <TT
|
|
CLASS="FILENAME"
|
|
>crt1.S</TT
|
|
>),
|
|
or those from the Linux kernel
|
|
(<TT
|
|
CLASS="FILENAME"
|
|
>exec.c</TT
|
|
> and <TT
|
|
CLASS="FILENAME"
|
|
>binfmt_*.c</TT
|
|
>
|
|
in <TT
|
|
CLASS="FILENAME"
|
|
>linux/fs/</TT
|
|
>).</P
|
|
></DIV
|
|
><DIV
|
|
CLASS="SECTION"
|
|
><HR><H2
|
|
CLASS="SECTION"
|
|
><A
|
|
NAME="AEN771">5.1.4. Hardware I/O under Linux</H2
|
|
><P
|
|
>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 <TT
|
|
CLASS="LITERAL"
|
|
>IO-Port-Programming</TT
|
|
> 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.</P
|
|
><P
|
|
>Particularly, if what you want is Graphics programming,
|
|
then do join one of the
|
|
<A
|
|
HREF="http://www.ggi-project.org/"
|
|
TARGET="_top"
|
|
>GGI</A
|
|
> or
|
|
<A
|
|
HREF="http://www.XFree86.org/"
|
|
TARGET="_top"
|
|
>XFree86</A
|
|
> projects.</P
|
|
><P
|
|
>Some people have even done better,
|
|
writing small and robust XFree86 drivers
|
|
in an interpreted domain-specific language,
|
|
<A
|
|
HREF="http://www.irisa.fr/compose/gal/"
|
|
TARGET="_top"
|
|
>GAL</A
|
|
>,
|
|
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?</P
|
|
><P
|
|
>Anyway, in all these cases, you'll be better when using GCC inline assembly
|
|
with the macros from <TT
|
|
CLASS="FILENAME"
|
|
>linux/asm/*.h</TT
|
|
>
|
|
than writing full assembly source files.</P
|
|
></DIV
|
|
><DIV
|
|
CLASS="SECTION"
|
|
><HR><H2
|
|
CLASS="SECTION"
|
|
><A
|
|
NAME="AEN782">5.1.5. Accessing 16-bit drivers from Linux/i386</H2
|
|
><P
|
|
>Such thing is theoretically possible
|
|
(proof: see how <A
|
|
HREF="http://www.dosemu.org"
|
|
TARGET="_top"
|
|
>DOSEMU</A
|
|
>
|
|
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 other programs in the
|
|
<A
|
|
HREF="ftp://tsx-11.mit.edu/pub/linux/ALPHA/dosemu/"
|
|
TARGET="_top"
|
|
>DOSEMU repository</A
|
|
>),
|
|
and sources for various low-level programs under Linux...
|
|
(perhaps GGI if it supports VESA).</P
|
|
><P
|
|
>Basically, you must either use 16-bit protected mode or vm86 mode.</P
|
|
><P
|
|
>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.</P
|
|
><P
|
|
>The later allows for more "compatibility" with vanilla 16-bit environments,
|
|
but requires more complicated handling.</P
|
|
><P
|
|
>In both cases, before you can jump to 16-bit code,
|
|
you must
|
|
|
|
<P
|
|
></P
|
|
><UL
|
|
><LI
|
|
><P
|
|
>mmap any absolute address used in the 16-bit code
|
|
(such as ROM, video buffers, DMA targets, and memory-mapped I/O)
|
|
from <TT
|
|
CLASS="FILENAME"
|
|
>/dev/mem</TT
|
|
> to your process' address space,</P
|
|
></LI
|
|
><LI
|
|
><P
|
|
>setup the LDT and/or vm86 mode monitor.</P
|
|
></LI
|
|
><LI
|
|
><P
|
|
>grab proper I/O permissions from the kernel (see the above section)</P
|
|
></LI
|
|
></UL
|
|
> </P
|
|
><P
|
|
>Again, carefully read the source for the stuff contributed
|
|
to the DOSEMU project,
|
|
particularly these mini-emulators for running ELKS
|
|
and/or simple <TT
|
|
CLASS="FILENAME"
|
|
>.COM</TT
|
|
> programs under Linux/i386.</P
|
|
></DIV
|
|
></DIV
|
|
><DIV
|
|
CLASS="SECTION"
|
|
><HR><H1
|
|
CLASS="SECTION"
|
|
><A
|
|
NAME="AEN801">5.2. DOS and Windows</H1
|
|
><P
|
|
>Most DOS extenders come with some interface to DOS services.
|
|
Read their docs about that,
|
|
but often, they just simulate <TT
|
|
CLASS="FUNCTION"
|
|
>int 0x21</TT
|
|
> 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).</P
|
|
><P
|
|
>Docs about DPMI (and much more) can be found on
|
|
<A
|
|
HREF="ftp://x2ftp.oulu.fi/pub/msdos/programming/"
|
|
TARGET="_top"
|
|
>ftp://x2ftp.oulu.fi/pub/msdos/programming/</A
|
|
>
|
|
(again, the original x2ftp site is closing (no more?), so use a
|
|
<A
|
|
HREF="ftp://ftp.lip6.fr/pub/pc/x2ftp/README.mirror_sites"
|
|
TARGET="_top"
|
|
>mirror site</A
|
|
>).</P
|
|
><P
|
|
>DJGPP comes with its own (limited)
|
|
<SPAN
|
|
CLASS="APPLICATION"
|
|
>glibc</SPAN
|
|
> derivative/subset/replacement, too.</P
|
|
><P
|
|
>It is possible to cross-compile from Linux to DOS,
|
|
see the <TT
|
|
CLASS="FILENAME"
|
|
>devel/msdos/</TT
|
|
> directory
|
|
of your local FTP mirror for metalab.unc.edu;
|
|
Also see the MOSS DOS-extender from the
|
|
<A
|
|
HREF="http://www.cs.utah.edu/projects/flux/"
|
|
TARGET="_top"
|
|
>Flux project</A
|
|
>
|
|
from the university of Utah.</P
|
|
><P
|
|
>Other documents and FAQs are more DOS-centered;
|
|
we do not recommend DOS development.</P
|
|
><DIV
|
|
CLASS="FORMALPARA"
|
|
><P
|
|
><B
|
|
>Windows and Co. </B
|
|
>This document is not about Windows programming,
|
|
you can find lots of documents about it everywhere..
|
|
The thing you should know is that
|
|
<A
|
|
HREF="http://www.cygnus.com"
|
|
TARGET="_top"
|
|
>Cygnus Solutions</A
|
|
>
|
|
developed the
|
|
<A
|
|
HREF="http://sourceware.cygnus.com/cygwin/"
|
|
TARGET="_top"
|
|
>cygwin32.dll library</A
|
|
>,
|
|
for GNU programs to run on Win32 platform; thus, you can use GCC, GAS,
|
|
all the GNU tools, and many other Unix applications.</P
|
|
></DIV
|
|
></DIV
|
|
><DIV
|
|
CLASS="SECTION"
|
|
><HR><H1
|
|
CLASS="SECTION"
|
|
><A
|
|
NAME="AEN819">5.3. Your own OS</H1
|
|
><P
|
|
>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).</P
|
|
><P
|
|
>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
|
|
<A
|
|
HREF="http://www.cs.utah.edu/projects/flux/oskit/"
|
|
TARGET="_top"
|
|
>Flux OS kit</A
|
|
>
|
|
(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.</P
|
|
><P
|
|
>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.</P
|
|
><P
|
|
>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:
|
|
<A
|
|
HREF="http://www.tunes.org/Review/OSes.html"
|
|
TARGET="_top"
|
|
>http://www.tunes.org/Review/OSes.html</A
|
|
></P
|
|
></DIV
|
|
></DIV
|
|
><DIV
|
|
CLASS="CHAPTER"
|
|
><HR><H1
|
|
><A
|
|
NAME="S-QUICK">Chapter 6. Quick start</H1
|
|
><DIV
|
|
CLASS="SECTION"
|
|
><H1
|
|
CLASS="SECTION"
|
|
><A
|
|
NAME="AEN829">6.1. Introduction</H1
|
|
><P
|
|
>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.</P
|
|
><P
|
|
>As you've read before, you can write for Linux in different ways;
|
|
I'll show how to use <EM
|
|
>direct</EM
|
|
> 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.</P
|
|
><P
|
|
>I will show the same sample program in two assemblers,
|
|
<B
|
|
CLASS="COMMAND"
|
|
>nasm</B
|
|
> and <B
|
|
CLASS="COMMAND"
|
|
>gas</B
|
|
>,
|
|
thus showing Intel and AT&T syntax.</P
|
|
><P
|
|
>You may also want to read <A
|
|
HREF="http://linuxassembly.org/intro.html"
|
|
TARGET="_top"
|
|
>Introduction to UNIX assembly programming</A
|
|
> tutorial,
|
|
it contains sample code for other UNIX-like OSes.</P
|
|
><DIV
|
|
CLASS="SECTION"
|
|
><HR><H2
|
|
CLASS="SECTION"
|
|
><A
|
|
NAME="AEN839">6.1.1. Tools you need</H2
|
|
><P
|
|
>First of all you need assembler (compiler) --
|
|
<B
|
|
CLASS="COMMAND"
|
|
>nasm</B
|
|
> or <B
|
|
CLASS="COMMAND"
|
|
>gas</B
|
|
>.</P
|
|
><P
|
|
>Second, you need a linker -- <B
|
|
CLASS="COMMAND"
|
|
>ld</B
|
|
>,
|
|
since assembler produces only object code. Almost all distributions have
|
|
<SPAN
|
|
CLASS="APPLICATION"
|
|
>gas</SPAN
|
|
> and <SPAN
|
|
CLASS="APPLICATION"
|
|
>ld</SPAN
|
|
>,
|
|
in the binutils package.</P
|
|
><P
|
|
>As for <SPAN
|
|
CLASS="APPLICATION"
|
|
>nasm</SPAN
|
|
>,
|
|
you may have to download and install binary packages for Linux and docs
|
|
from the <A
|
|
HREF="#P-NASM-WHERE"
|
|
>nasm site</A
|
|
>;
|
|
note that several distributions (Stampede, Debian, SuSe, Mandrake)
|
|
already have <SPAN
|
|
CLASS="APPLICATION"
|
|
>nasm</SPAN
|
|
>, check first.</P
|
|
><P
|
|
>If you're going to dig in, you should also install include files for your OS,
|
|
and if possible, kernel source.</P
|
|
></DIV
|
|
></DIV
|
|
><DIV
|
|
CLASS="SECTION"
|
|
><HR><H1
|
|
CLASS="SECTION"
|
|
><A
|
|
NAME="AEN853">6.2. Hello, world!</H1
|
|
><DIV
|
|
CLASS="SECTION"
|
|
><H2
|
|
CLASS="SECTION"
|
|
><A
|
|
NAME="AEN855">6.2.1. Program layout</H2
|
|
><P
|
|
>Linux is 32-bit, runs in protected mode, has flat memory model,
|
|
and uses the ELF format for binaries.</P
|
|
><P
|
|
>A program can be divided into sections:
|
|
<TT
|
|
CLASS="LITERAL"
|
|
>.text</TT
|
|
> for your code (read-only),
|
|
<TT
|
|
CLASS="LITERAL"
|
|
>.data</TT
|
|
> for your data (read-write),
|
|
<TT
|
|
CLASS="LITERAL"
|
|
>.bss</TT
|
|
> 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 <TT
|
|
CLASS="LITERAL"
|
|
>.text</TT
|
|
> section.</P
|
|
><P
|
|
>Now we will write our first program. Here is sample code:</P
|
|
></DIV
|
|
><DIV
|
|
CLASS="SECTION"
|
|
><HR><H2
|
|
CLASS="SECTION"
|
|
><A
|
|
NAME="AEN864">6.2.2. NASM (hello.asm)</H2
|
|
><P
|
|
><TABLE
|
|
BORDER="0"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="PROGRAMLISTING"
|
|
>section .data ;section declaration
|
|
|
|
msg db "Hello, world!",0xa ;our dear string
|
|
len equ $ - msg ;length of our dear string
|
|
|
|
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 </PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></P
|
|
></DIV
|
|
><DIV
|
|
CLASS="SECTION"
|
|
><HR><H2
|
|
CLASS="SECTION"
|
|
><A
|
|
NAME="AEN868">6.2.3. GAS (hello.S)</H2
|
|
><P
|
|
><TABLE
|
|
BORDER="0"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="PROGRAMLISTING"
|
|
>.data # section declaration
|
|
|
|
msg:
|
|
.ascii "Hello, world!\n" # our dear string
|
|
len = . - msg # length of our dear string
|
|
|
|
.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</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></P
|
|
></DIV
|
|
></DIV
|
|
><DIV
|
|
CLASS="SECTION"
|
|
><HR><H1
|
|
CLASS="SECTION"
|
|
><A
|
|
NAME="AEN872">6.3. Building an executable</H1
|
|
><DIV
|
|
CLASS="SECTION"
|
|
><H2
|
|
CLASS="SECTION"
|
|
><A
|
|
NAME="AEN874">6.3.1. Producing object code</H2
|
|
><P
|
|
>First step of building an executable is compiling (or assembling)
|
|
object file from the source:</P
|
|
><P
|
|
>For <SPAN
|
|
CLASS="APPLICATION"
|
|
>nasm</SPAN
|
|
> example:</P
|
|
><P
|
|
><TABLE
|
|
BORDER="1"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="SCREEN"
|
|
>$ nasm -f elf hello.asm</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></P
|
|
><P
|
|
>For <SPAN
|
|
CLASS="APPLICATION"
|
|
>gas</SPAN
|
|
> example:</P
|
|
><P
|
|
><TABLE
|
|
BORDER="1"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="SCREEN"
|
|
>$ as -o hello.o hello.S</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></P
|
|
><P
|
|
>This makes <TT
|
|
CLASS="FILENAME"
|
|
>hello.o</TT
|
|
> object file.</P
|
|
></DIV
|
|
><DIV
|
|
CLASS="SECTION"
|
|
><HR><H2
|
|
CLASS="SECTION"
|
|
><A
|
|
NAME="AEN887">6.3.2. Producing executable</H2
|
|
><P
|
|
>Second step is producing executable file itself
|
|
from the object file by invoking linker:</P
|
|
><P
|
|
><TABLE
|
|
BORDER="1"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="SCREEN"
|
|
>$ ld -s -o hello hello.o</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></P
|
|
><P
|
|
>This will finally build <TT
|
|
CLASS="FILENAME"
|
|
>hello</TT
|
|
> executable.</P
|
|
><P
|
|
>Hey, try to run it... Works? That's it. Pretty simple.</P
|
|
></DIV
|
|
></DIV
|
|
></DIV
|
|
><DIV
|
|
CLASS="CHAPTER"
|
|
><HR><H1
|
|
><A
|
|
NAME="S-RES">Chapter 7. Resources</H1
|
|
><DIV
|
|
CLASS="SIMPLESECT"
|
|
><H4
|
|
CLASS="SIMPLESECT"
|
|
><A
|
|
NAME="S-RES-URL">7.1. Pointers</H4
|
|
><P
|
|
>Your main resource for Linux/UNIX assembly programming material is:</P
|
|
><A
|
|
NAME="AEN900"><BLOCKQUOTE
|
|
CLASS="BLOCKQUOTE"
|
|
><P
|
|
><A
|
|
HREF="http://linuxassembly.org/resources.html"
|
|
TARGET="_top"
|
|
>http://linuxassembly.org/resources.html</A
|
|
></P
|
|
></BLOCKQUOTE
|
|
><P
|
|
>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.</P
|
|
><P
|
|
>If you are new to assembly in general, here are few starting pointers:
|
|
|
|
<A
|
|
NAME="S-RES-GEN"
|
|
></A
|
|
>
|
|
|
|
<P
|
|
></P
|
|
><UL
|
|
><LI
|
|
><P
|
|
><A
|
|
HREF="http://webster.cs.ucr.edu/Page_asm/ArtOfAsm.html"
|
|
TARGET="_top"
|
|
>The Art Of Assembly</A
|
|
></P
|
|
></LI
|
|
><LI
|
|
><P
|
|
><A
|
|
HREF="http://www2.dgsys.com/~raymoon/faq/"
|
|
TARGET="_top"
|
|
>x86 assembly FAQ</A
|
|
></P
|
|
></LI
|
|
><LI
|
|
><P
|
|
><A
|
|
HREF="ftp://ftp.luth.se/pub/msdos/"
|
|
TARGET="_top"
|
|
>ftp.luth.se</A
|
|
>
|
|
mirrors the hornet and x2ftp former archives of msdos assembly coding stuff</P
|
|
></LI
|
|
><LI
|
|
><P
|
|
><A
|
|
HREF="http://www.koth.org"
|
|
TARGET="_top"
|
|
>CoreWars</A
|
|
>,
|
|
a fun way to learn assembly in general</P
|
|
></LI
|
|
><LI
|
|
><P
|
|
>Usenet:
|
|
<A
|
|
HREF="news://comp.lang.asm.x86"
|
|
TARGET="_top"
|
|
>comp.lang.asm.x86</A
|
|
>;
|
|
<A
|
|
HREF="news://alt.lang.asm"
|
|
TARGET="_top"
|
|
>alt.lang.asm</A
|
|
></P
|
|
></LI
|
|
></UL
|
|
> </P
|
|
></DIV
|
|
><DIV
|
|
CLASS="SIMPLESECT"
|
|
><HR><H4
|
|
CLASS="SIMPLESECT"
|
|
><A
|
|
NAME="S-RES-LIST">7.2. Mailing list</H4
|
|
><P
|
|
>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.</P
|
|
><P
|
|
>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!).</P
|
|
><P
|
|
>Mailing list address is <TT
|
|
CLASS="EMAIL"
|
|
><<A
|
|
HREF="mailto:linux-assembly@vger.kernel.org"
|
|
>linux-assembly@vger.kernel.org</A
|
|
>></TT
|
|
>.</P
|
|
><P
|
|
>To subscribe send a messgage to <TT
|
|
CLASS="EMAIL"
|
|
><<A
|
|
HREF="mailto:majordomo@vger.kernel.org"
|
|
>majordomo@vger.kernel.org</A
|
|
>></TT
|
|
>
|
|
with the following line in the body of the message:
|
|
|
|
<TABLE
|
|
BORDER="0"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="PROGRAMLISTING"
|
|
>subscribe linux-assembly</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></P
|
|
><P
|
|
>Detailed information and list archives are available at
|
|
<A
|
|
HREF="http://linuxassembly.org/list.html"
|
|
TARGET="_top"
|
|
>http://linuxassembly.org/list.html</A
|
|
>.</P
|
|
></DIV
|
|
></DIV
|
|
><DIV
|
|
CLASS="CHAPTER"
|
|
><HR><H1
|
|
><A
|
|
NAME="S-FAQ">Chapter 8. Frequently Asked Questions</H1
|
|
><P
|
|
>Here are frequently asked questions (with answers)
|
|
about Linux assembly programming.
|
|
Some of the questions (and the answers) were taken from the
|
|
the <A
|
|
HREF="#S-RES-LIST"
|
|
>linux-assembly mailing list</A
|
|
>.</P
|
|
><DIV
|
|
CLASS="QANDASET"
|
|
><DL
|
|
><DT
|
|
>8.1. <A
|
|
HREF="#AEN940"
|
|
>How do I do graphics programming in Linux?</A
|
|
></DT
|
|
><DT
|
|
>8.2. <A
|
|
HREF="#AEN948"
|
|
>How do I debug pure assembly code under Linux?</A
|
|
></DT
|
|
><DT
|
|
>8.3. <A
|
|
HREF="#AEN971"
|
|
>Any other useful debugging tools?</A
|
|
></DT
|
|
><DT
|
|
>8.4. <A
|
|
HREF="#AEN981"
|
|
>How do I access BIOS functions from Linux (BSD, BeOS, etc)?</A
|
|
></DT
|
|
><DT
|
|
>8.5. <A
|
|
HREF="#AEN988"
|
|
>Is it possible to write kernel modules in assembly?</A
|
|
></DT
|
|
><DT
|
|
>8.6. <A
|
|
HREF="#AEN1005"
|
|
>How do I allocate memory dynamically?</A
|
|
></DT
|
|
><DT
|
|
>8.7. <A
|
|
HREF="#AEN1018"
|
|
>I can't understand how to use <TT
|
|
CLASS="FUNCTION"
|
|
>select</TT
|
|
> system call!</A
|
|
></DT
|
|
></DL
|
|
><DIV
|
|
CLASS="QANDAENTRY"
|
|
><DIV
|
|
CLASS="QUESTION"
|
|
><P
|
|
><A
|
|
NAME="AEN940"><B
|
|
>8.1. </B
|
|
>How do I do graphics programming in Linux?</P
|
|
></DIV
|
|
><DIV
|
|
CLASS="ANSWER"
|
|
><P
|
|
><B
|
|
> </B
|
|
>An answer from <A
|
|
HREF="mailto:paulf@icom.co.za"
|
|
TARGET="_top"
|
|
>Paul Furber</A
|
|
>:</P
|
|
><P
|
|
><TABLE
|
|
BORDER="1"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="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.</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></P
|
|
></DIV
|
|
></DIV
|
|
><DIV
|
|
CLASS="QANDAENTRY"
|
|
><DIV
|
|
CLASS="QUESTION"
|
|
><P
|
|
><A
|
|
NAME="AEN948"><B
|
|
>8.2. </B
|
|
>How do I debug pure assembly code under Linux?</P
|
|
></DIV
|
|
><DIV
|
|
CLASS="ANSWER"
|
|
><P
|
|
><B
|
|
> </B
|
|
>There's an early version of the
|
|
<A
|
|
HREF="http://ellipse.mcs.drexel.edu/ald.html"
|
|
TARGET="_top"
|
|
>Assembly Language Debugger</A
|
|
>,
|
|
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!</P
|
|
><P
|
|
>You can also try <B
|
|
CLASS="COMMAND"
|
|
>gdb</B
|
|
> ;).
|
|
Although it is source-level debugger, it can be used to debug
|
|
pure assembly code, and with some trickery you can make
|
|
<B
|
|
CLASS="COMMAND"
|
|
>gdb</B
|
|
> 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 <A
|
|
HREF="mailto:dl@gazeta.ru"
|
|
TARGET="_top"
|
|
>Dmitry Bakhvalov</A
|
|
>:</P
|
|
><P
|
|
><TABLE
|
|
BORDER="1"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="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.</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></P
|
|
><P
|
|
>An additional note from ???:</P
|
|
><P
|
|
><TABLE
|
|
BORDER="1"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="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.</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></P
|
|
><P
|
|
>If you want to set breakpoints across your code, you can just use
|
|
<TT
|
|
CLASS="FUNCTION"
|
|
>int 3</TT
|
|
> instruction as breakpoint
|
|
(instead of entering address manually in <B
|
|
CLASS="COMMAND"
|
|
>gdb</B
|
|
>).</P
|
|
><P
|
|
>If you're using <SPAN
|
|
CLASS="APPLICATION"
|
|
>gas</SPAN
|
|
>, you should consult
|
|
<SPAN
|
|
CLASS="APPLICATION"
|
|
>gas</SPAN
|
|
> and <SPAN
|
|
CLASS="APPLICATION"
|
|
>gdb</SPAN
|
|
> related
|
|
<A
|
|
HREF="http://linuxassembly.org/resources.html#tutorials"
|
|
TARGET="_top"
|
|
>tutorials</A
|
|
>.</P
|
|
></DIV
|
|
></DIV
|
|
><DIV
|
|
CLASS="QANDAENTRY"
|
|
><DIV
|
|
CLASS="QUESTION"
|
|
><P
|
|
><A
|
|
NAME="AEN971"><B
|
|
>8.3. </B
|
|
>Any other useful debugging tools?</P
|
|
></DIV
|
|
><DIV
|
|
CLASS="ANSWER"
|
|
><P
|
|
><B
|
|
> </B
|
|
>Definitely <B
|
|
CLASS="COMMAND"
|
|
>strace</B
|
|
> can help a lot
|
|
(<B
|
|
CLASS="COMMAND"
|
|
>ktrace</B
|
|
> and <B
|
|
CLASS="COMMAND"
|
|
>kdump</B
|
|
>
|
|
on FreeBSD),
|
|
it is used to trace system calls and signals.
|
|
Read its manual page (<B
|
|
CLASS="COMMAND"
|
|
>man strace</B
|
|
>) and
|
|
<B
|
|
CLASS="COMMAND"
|
|
>strace --help</B
|
|
> output for details.</P
|
|
></DIV
|
|
></DIV
|
|
><DIV
|
|
CLASS="QANDAENTRY"
|
|
><DIV
|
|
CLASS="QUESTION"
|
|
><P
|
|
><A
|
|
NAME="AEN981"><B
|
|
>8.4. </B
|
|
>How do I access BIOS functions from Linux (BSD, BeOS, etc)?</P
|
|
></DIV
|
|
><DIV
|
|
CLASS="ANSWER"
|
|
><P
|
|
><B
|
|
> </B
|
|
>Short answer is -- noway. This is protected mode, use OS services instead.
|
|
Again, you can't use <TT
|
|
CLASS="FUNCTION"
|
|
>int 0x10</TT
|
|
>,
|
|
<TT
|
|
CLASS="FUNCTION"
|
|
>int 0x13</TT
|
|
>, 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.</P
|
|
></DIV
|
|
></DIV
|
|
><DIV
|
|
CLASS="QANDAENTRY"
|
|
><DIV
|
|
CLASS="QUESTION"
|
|
><P
|
|
><A
|
|
NAME="AEN988"><B
|
|
>8.5. </B
|
|
>Is it possible to write kernel modules in assembly?</P
|
|
></DIV
|
|
><DIV
|
|
CLASS="ANSWER"
|
|
><P
|
|
><B
|
|
> </B
|
|
>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.</P
|
|
><P
|
|
>Meanwhile, here's an example of a minimum dumb kernel module
|
|
(<TT
|
|
CLASS="FILENAME"
|
|
>module.asm</TT
|
|
>)
|
|
(source is based on example by mammon_ from APJ #8):</P
|
|
><P
|
|
><TABLE
|
|
BORDER="0"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="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</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></P
|
|
><P
|
|
>The only thing this example does is reporting its actions.
|
|
Modify <TT
|
|
CLASS="FILENAME"
|
|
>kernel_version</TT
|
|
> to match yours, and build module with:</P
|
|
><P
|
|
><TABLE
|
|
BORDER="1"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="SCREEN"
|
|
>$ nasm -f elf -o module.m module.asm</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></P
|
|
><P
|
|
><TABLE
|
|
BORDER="1"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="SCREEN"
|
|
>$ ld -r -o module.o module.m</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></P
|
|
><P
|
|
>Now you can play with it using <B
|
|
CLASS="COMMAND"
|
|
>insmod/rmmod/lsmod</B
|
|
>
|
|
(root privilidged are required); a lot of fun, huh?</P
|
|
></DIV
|
|
></DIV
|
|
><DIV
|
|
CLASS="QANDAENTRY"
|
|
><DIV
|
|
CLASS="QUESTION"
|
|
><P
|
|
><A
|
|
NAME="AEN1005"><B
|
|
>8.6. </B
|
|
>How do I allocate memory dynamically?</P
|
|
></DIV
|
|
><DIV
|
|
CLASS="ANSWER"
|
|
><P
|
|
><B
|
|
> </B
|
|
>A laconic answer from <A
|
|
HREF="mailto:phpr@snafu.de"
|
|
TARGET="_top"
|
|
>H-Peter Recktenwald</A
|
|
>:</P
|
|
><P
|
|
><TABLE
|
|
BORDER="0"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="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</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></P
|
|
></DIV
|
|
><DIV
|
|
CLASS="ANSWER"
|
|
><P
|
|
><B
|
|
> </B
|
|
>An extensive answer from <A
|
|
HREF="mailto:ee97034@fe.up.pt"
|
|
TARGET="_top"
|
|
>Tiago Gasiba</A
|
|
>:</P
|
|
><P
|
|
><TABLE
|
|
BORDER="0"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="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</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></P
|
|
></DIV
|
|
></DIV
|
|
><DIV
|
|
CLASS="QANDAENTRY"
|
|
><DIV
|
|
CLASS="QUESTION"
|
|
><P
|
|
><A
|
|
NAME="AEN1018"><B
|
|
>8.7. </B
|
|
>I can't understand how to use <TT
|
|
CLASS="FUNCTION"
|
|
>select</TT
|
|
> system call!</P
|
|
></DIV
|
|
><DIV
|
|
CLASS="ANSWER"
|
|
><P
|
|
><B
|
|
> </B
|
|
>An answer from <A
|
|
HREF="mailto:mochel@transmeta.com"
|
|
TARGET="_top"
|
|
>Patrick Mochel</A
|
|
>:</P
|
|
><P
|
|
><TABLE
|
|
BORDER="0"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="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. ;-)</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></P
|
|
></DIV
|
|
></DIV
|
|
></DIV
|
|
><P
|
|
><EM
|
|
>That's all for now, folks</EM
|
|
>.</P
|
|
></DIV
|
|
><DIV
|
|
CLASS="APPENDIX"
|
|
><HR><H1
|
|
><A
|
|
NAME="A-HISTORY">Appendix A. History</H1
|
|
><P
|
|
>Each version includes a few fixes and minor corrections,
|
|
that need not to be repeatedly mentioned every time.</P
|
|
><P
|
|
><DIV
|
|
CLASS="REVHISTORY"
|
|
><TABLE
|
|
WIDTH="100%"
|
|
BORDER="0"
|
|
><TR
|
|
><TH
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
COLSPAN="3"
|
|
><B
|
|
>Revision History</B
|
|
></TH
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revision 0.6f</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>17 Aug 2002</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revised by: konst</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
COLSPAN="3"
|
|
>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;</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revision 0.6e</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>12 Jan 2002</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revised by: konst</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
COLSPAN="3"
|
|
>Added URL describing GAS Intel syntax;
|
|
Added OSIMPA(former SHASM);
|
|
Added YASM;
|
|
FAQ update.</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revision 0.6d</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>18 Mar 2001</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revised by: konst</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
COLSPAN="3"
|
|
>Added Free Pascal;
|
|
new NASM URL again</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revision 0.6c</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>15 Feb 2001</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revised by: konst</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
COLSPAN="3"
|
|
>Added SHASM;
|
|
new answer in FAQ, new NASM URL, new mailing list address</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revision 0.6b</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>21 Jan 2001</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revised by: konst</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
COLSPAN="3"
|
|
>new questions in FAQ, corrected few URLs</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revision 0.6a</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>10 Dec 2000</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revised by: konst</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
COLSPAN="3"
|
|
>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.</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revision 0.6</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>11 Nov 2000</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revised by: konst</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
COLSPAN="3"
|
|
>HOWTO is completely rewritten using DocBook DTD.
|
|
Layout is totally rearranged;
|
|
too much changes to list them here.</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revision 0.5n</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>07 Nov 2000</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revised by: konst</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
COLSPAN="3"
|
|
>Added question regarding kernel modules to <A
|
|
HREF="#S-FAQ"
|
|
>FAQ</A
|
|
>,
|
|
fixed NASM URLs, GAS has Intel syntax too</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revision 0.5m</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>22 Oct 2000</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revised by: konst</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
COLSPAN="3"
|
|
>Linux 2.4 system calls can have 6 args,
|
|
Added ALD note to <A
|
|
HREF="#S-FAQ"
|
|
>FAQ</A
|
|
>,
|
|
fixed mailing list subscribe address</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revision 0.5l</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>23 Aug 2000</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revised by: konst</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
COLSPAN="3"
|
|
>Added TDASM, updates on NASM</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revision 0.5k</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>11 Jul 2000</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revised by: konst</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
COLSPAN="3"
|
|
>Few additions to FAQ</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revision 0.5j</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>14 Jun 2000</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revised by: konst</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
COLSPAN="3"
|
|
>Complete rearrangement of <A
|
|
HREF="#S-INTRO"
|
|
>Introduction</A
|
|
> and <A
|
|
HREF="#S-RES"
|
|
>Resources</A
|
|
> sections.
|
|
<A
|
|
HREF="#S-FAQ"
|
|
>FAQ</A
|
|
> added to <A
|
|
HREF="#S-RES"
|
|
>Resources</A
|
|
>, misc cleanups and additions.</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revision 0.5i</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>04 May 2000</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revised by: konst</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
COLSPAN="3"
|
|
>Added HLA, TALC;
|
|
rearrangements in <A
|
|
HREF="#S-RES"
|
|
>Resources</A
|
|
>, <A
|
|
HREF="#S-QUICK"
|
|
>Quick Start</A
|
|
> <A
|
|
HREF="#S-ASSEM"
|
|
>Assemblers</A
|
|
> sections. Few new pointers.</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revision 0.5h</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>09 Apr 2000</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revised by: konst</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
COLSPAN="3"
|
|
>finally managed to state LDP license on document,
|
|
new resources added, misc fixes</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revision 0.5g</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>26 Mar 2000</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revised by: konst</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
COLSPAN="3"
|
|
>new resources on different CPUs</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revision 0.5f</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>02 Mar 2000</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revised by: konst</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
COLSPAN="3"
|
|
>new resources, misc corrections</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revision 0.5e</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>10 Feb 2000</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revised by: konst</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
COLSPAN="3"
|
|
>URL updates, changes in GAS example</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revision 0.5d</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>01 Feb 2000</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revised by: konst</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
COLSPAN="3"
|
|
><A
|
|
HREF="#S-RES"
|
|
>Resources</A
|
|
> (former "Pointers") section completely redone,
|
|
various URL updates.</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revision 0.5c</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>05 Dec 1999</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revised by: konst</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
COLSPAN="3"
|
|
>New pointers, updates and some rearrangements.
|
|
Rewrite of sgml source.</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revision 0.5b</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>19 Sep 1999</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revised by: konst</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
COLSPAN="3"
|
|
>Discussion about libc or not libc continues.
|
|
New web pointers and and overall updates.</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revision 0.5a</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>01 Aug 1999</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revised by: konst</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
COLSPAN="3"
|
|
><A
|
|
HREF="#S-QUICK"
|
|
>Quick Start</A
|
|
> section rearranged, added GAS example.
|
|
Several new web pointers.</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revision 0.5</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>01 Aug 1999</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revised by: konstfare</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
COLSPAN="3"
|
|
>GAS has 16-bit mode.
|
|
New maintainer (at last): Konstantin Boldyshev.
|
|
Discussion about libc or not libc.
|
|
Added <A
|
|
HREF="#S-QUICK"
|
|
>Quick Start</A
|
|
> section with examples of assembly code.</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revision 0.4q</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>22 Jun 1999</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revised by: fare</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
COLSPAN="3"
|
|
>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.</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revision 0.4p</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>06 Jun 1999</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revised by: fare</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
COLSPAN="3"
|
|
>clean up and updates</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revision 0.4o</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>01 Dec 1998</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revised by: fare</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
COLSPAN="3"
|
|
></TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revision 0.4m</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>23 Mar 1998</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revised by: fare</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
COLSPAN="3"
|
|
>corrections about gcc invocation</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revision 0.4l</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>16 Nov 1997</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revised by: fare</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
COLSPAN="3"
|
|
>release for LSL 6th edition</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revision 0.4k</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>19 Oct 1997</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revised by: fare</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
COLSPAN="3"
|
|
></TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revision 0.4j</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>07 Sep 1997</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revised by: fare</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
COLSPAN="3"
|
|
></TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revision 0.4i</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>17 Jul 1997</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revised by: fare</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
COLSPAN="3"
|
|
>info on 16-bit mode access from Linux</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revision 0.4h</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>19 Jun 1997</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revised by: fare</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
COLSPAN="3"
|
|
>still more on "how not to use assembly";
|
|
updates on NASM, GAS.</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revision 0.4g</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>30 Mar 1997</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revised by: fare</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
COLSPAN="3"
|
|
></TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revision 0.4f</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>20 Mar 1997</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revised by: fare</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
COLSPAN="3"
|
|
></TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revision 0.4e</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>13 Mar 1997</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revised by: fare</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
COLSPAN="3"
|
|
>Release for DrLinux</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revision 0.4d</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>28 Feb 1997</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revised by: fare</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
COLSPAN="3"
|
|
>Vapor announce of a new Assembly-HOWTO maintainer</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revision 0.4c</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>09 Feb 1997</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revised by: fare</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
COLSPAN="3"
|
|
>Added section <A
|
|
HREF="#S-DOYOU"
|
|
>Do you need assembly?</A
|
|
>.</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revision 0.4b</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>03 Feb 1997</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revised by: fare</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
COLSPAN="3"
|
|
>NASM moved: now is before AS86</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revision 0.4a</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>20 Jan 1997</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revised by: fare</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
COLSPAN="3"
|
|
>CREDITS section added</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revision 0.4</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>20 Jan 1997</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revised by: fare</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
COLSPAN="3"
|
|
>first release of the HOWTO as such</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revision 0.4pre1</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>13 Jan 1997</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revised by: fare</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
COLSPAN="3"
|
|
>text mini-HOWTO transformed into a full linuxdoc-sgml HOWTO,
|
|
to see what the SGML tools are like</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revision 0.3l</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>11 Jan 1997</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revised by: fare</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
COLSPAN="3"
|
|
></TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revision 0.3k</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>19 Dec 1996</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revised by: fare</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
COLSPAN="3"
|
|
>What? I had forgotten to point to terse???</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revision 0.3j</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>24 Nov 1996</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revised by: fare</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
COLSPAN="3"
|
|
>point to French translated version</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revision 0.3i</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>16 Nov 1996</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revised by: fare</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
COLSPAN="3"
|
|
>NASM is getting pretty slick</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revision 0.3h</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>06 Nov 1996</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revised by: fare</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
COLSPAN="3"
|
|
>more about cross-compiling -- See on sunsite: devel/msdos/</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revision 0.3g</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>02 Nov 1996</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revised by: fare</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
COLSPAN="3"
|
|
>Created the History. Added pointers in cross-compiling section.
|
|
Added section about I/O programming under Linux (particularly video).</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revision 0.3f</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>17 Oct 1996</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revised by: fare</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
COLSPAN="3"
|
|
></TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revision 0.3c</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>15 Jun 1996</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revised by: fare</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
COLSPAN="3"
|
|
></TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revision 0.2</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>04 May 1996</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revised by: fare</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
COLSPAN="3"
|
|
></TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revision 0.1</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>23 Apr 1996</TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
>Revised by: fare</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
ALIGN="LEFT"
|
|
COLSPAN="3"
|
|
>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"</TD
|
|
></TR
|
|
></TABLE
|
|
></DIV
|
|
></P
|
|
></DIV
|
|
><DIV
|
|
CLASS="APPENDIX"
|
|
><HR><H1
|
|
><A
|
|
NAME="A-ACK">Appendix B. Acknowledgements</H1
|
|
><P
|
|
>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:
|
|
|
|
<P
|
|
></P
|
|
><UL
|
|
><LI
|
|
><P
|
|
><A
|
|
HREF="mailto:buried.alive@in.mail"
|
|
TARGET="_top"
|
|
>Linus Torvalds</A
|
|
>
|
|
for Linux</P
|
|
></LI
|
|
><LI
|
|
><P
|
|
><A
|
|
NAME="BDE"
|
|
></A
|
|
>
|
|
<A
|
|
HREF="mailto:bde@zeta.org.au"
|
|
TARGET="_top"
|
|
>Bruce Evans</A
|
|
>
|
|
for bcc from which as86 is extracted</P
|
|
></LI
|
|
><LI
|
|
><P
|
|
><A
|
|
HREF="mailto:anakin@pobox.com"
|
|
TARGET="_top"
|
|
>Simon Tatham</A
|
|
> and
|
|
<A
|
|
HREF="mailto:jules@earthcorp.com"
|
|
TARGET="_top"
|
|
>Julian Hall</A
|
|
>
|
|
for NASM</P
|
|
></LI
|
|
><LI
|
|
><P
|
|
><A
|
|
HREF="mailto:gregh@metalab.unc.edu"
|
|
TARGET="_top"
|
|
>Greg Hankins</A
|
|
> and now
|
|
<A
|
|
HREF="mailto:linux-howto@metalab.unc.edu"
|
|
TARGET="_top"
|
|
>Tim Bynum</A
|
|
>
|
|
for maintaining HOWTOs</P
|
|
></LI
|
|
><LI
|
|
><P
|
|
><A
|
|
HREF="mailto:raymoon@moonware.dgsys.com"
|
|
TARGET="_top"
|
|
>Raymond Moon</A
|
|
>
|
|
for his FAQ</P
|
|
></LI
|
|
><LI
|
|
><P
|
|
><A
|
|
HREF="mailto:dumas@linux.eu.org"
|
|
TARGET="_top"
|
|
>Eric Dumas</A
|
|
>
|
|
for his translation of the mini-HOWTO into French
|
|
(sad thing for the original author to be French and write in English)</P
|
|
></LI
|
|
><LI
|
|
><P
|
|
><A
|
|
HREF="mailto:paul@geeky1.ebtech.net"
|
|
TARGET="_top"
|
|
>Paul Anderson</A
|
|
> and
|
|
<A
|
|
HREF="mailto:rahim@megsinet.net"
|
|
TARGET="_top"
|
|
>Rahim Azizarab</A
|
|
>
|
|
for helping me, if not for taking over the HOWTO</P
|
|
></LI
|
|
><LI
|
|
><P
|
|
><A
|
|
HREF="mailto:pcg@goof.com"
|
|
TARGET="_top"
|
|
>Marc Lehman</A
|
|
>
|
|
for his insight on GCC invocation</P
|
|
></LI
|
|
><LI
|
|
><P
|
|
><A
|
|
HREF="mailto:ams@wiw.org"
|
|
TARGET="_top"
|
|
>Abhijit Menon-Sen</A
|
|
>
|
|
for helping me figure out the argument passing convention</P
|
|
></LI
|
|
></UL
|
|
> </P
|
|
></DIV
|
|
><DIV
|
|
CLASS="APPENDIX"
|
|
><HR><H1
|
|
><A
|
|
NAME="A-ENDOR">Appendix C. Endorsements</H1
|
|
><P
|
|
>This version of the document is endorsed by
|
|
<A
|
|
HREF="#KONST"
|
|
>Konstantin Boldyshev</A
|
|
>.</P
|
|
><P
|
|
>Modifications (including translations) must remove this appendix
|
|
according to the <A
|
|
HREF="#A-GFDL"
|
|
>license agreement</A
|
|
>.</P
|
|
><P
|
|
><TT
|
|
CLASS="LITERAL"
|
|
>$Id: Assembly-HOWTO.sgml,v 1.7 2002/08/17 08:35:59 konst Exp $</TT
|
|
></P
|
|
></DIV
|
|
><DIV
|
|
CLASS="APPENDIX"
|
|
><HR><H1
|
|
><A
|
|
NAME="A-GFDL">Appendix D. GNU Free Documentation License</H1
|
|
><P
|
|
><P
|
|
CLASS="LITERALLAYOUT"
|
|
>GNU Free Documentation License<br>
|
|
Version 1.1, March 2000<br>
|
|
<br>
|
|
Copyright (C) 2000 Free Software Foundation, Inc.<br>
|
|
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA<br>
|
|
Everyone is permitted to copy and distribute verbatim copies<br>
|
|
of this license document, but changing it is not allowed.</P
|
|
></P
|
|
><P
|
|
><P
|
|
></P
|
|
><DIV
|
|
CLASS="VARIABLELIST"
|
|
><DL
|
|
><DT
|
|
>0. PREAMBLE</DT
|
|
><DD
|
|
><P
|
|
>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.</P
|
|
><P
|
|
>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.</P
|
|
><P
|
|
>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.</P
|
|
></DD
|
|
><DT
|
|
>1. APPLICABILITY AND DEFINITIONS</DT
|
|
><DD
|
|
><P
|
|
>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".</P
|
|
><P
|
|
>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.</P
|
|
><P
|
|
>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.</P
|
|
><P
|
|
>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.</P
|
|
><P
|
|
>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.</P
|
|
><P
|
|
>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".</P
|
|
><P
|
|
>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.</P
|
|
><P
|
|
>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.</P
|
|
></DD
|
|
><DT
|
|
>2. VERBATIM COPYING</DT
|
|
><DD
|
|
><P
|
|
>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.</P
|
|
><P
|
|
>You may also lend copies, under the same conditions stated
|
|
above, and you may publicly display copies.</P
|
|
></DD
|
|
><DT
|
|
>3. COPYING IN QUANTITY</DT
|
|
><DD
|
|
><P
|
|
>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.</P
|
|
><P
|
|
>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.</P
|
|
><P
|
|
>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.</P
|
|
><P
|
|
>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.</P
|
|
></DD
|
|
><DT
|
|
>4. MODIFICATIONS</DT
|
|
><DD
|
|
><P
|
|
>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:</P
|
|
><P
|
|
></P
|
|
><OL
|
|
TYPE="A"
|
|
><LI
|
|
><P
|
|
>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.</P
|
|
></LI
|
|
><LI
|
|
><P
|
|
>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).</P
|
|
></LI
|
|
><LI
|
|
><P
|
|
>State on the Title page
|
|
the name of the publisher of the Modified Version, as the
|
|
publisher.</P
|
|
></LI
|
|
><LI
|
|
><P
|
|
>Preserve all the
|
|
copyright notices of the Document.</P
|
|
></LI
|
|
><LI
|
|
><P
|
|
>Add an appropriate
|
|
copyright notice for your modifications adjacent to the other
|
|
copyright notices.</P
|
|
></LI
|
|
><LI
|
|
><P
|
|
>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.</P
|
|
></LI
|
|
><LI
|
|
><P
|
|
>Preserve in that license
|
|
notice the full lists of Invariant Sections and required Cover
|
|
Texts given in the Document's license notice.</P
|
|
></LI
|
|
><LI
|
|
><P
|
|
>Include an unaltered
|
|
copy of this License.</P
|
|
></LI
|
|
><LI
|
|
><P
|
|
>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.</P
|
|
></LI
|
|
><LI
|
|
><P
|
|
>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.</P
|
|
></LI
|
|
><LI
|
|
><P
|
|
>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.</P
|
|
></LI
|
|
><LI
|
|
><P
|
|
>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.</P
|
|
></LI
|
|
><LI
|
|
><P
|
|
>Delete any section
|
|
entitled "Endorsements". Such a section may not be included in
|
|
the Modified Version.</P
|
|
></LI
|
|
><LI
|
|
><P
|
|
>Do not retitle any
|
|
existing section as "Endorsements" or to conflict in title with
|
|
any Invariant Section.</P
|
|
></LI
|
|
></OL
|
|
><P
|
|
>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.</P
|
|
><P
|
|
>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.</P
|
|
><P
|
|
>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.</P
|
|
><P
|
|
>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.</P
|
|
></DD
|
|
><DT
|
|
>5. COMBINING DOCUMENTS</DT
|
|
><DD
|
|
><P
|
|
>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.</P
|
|
><P
|
|
>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.</P
|
|
><P
|
|
>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."</P
|
|
></DD
|
|
><DT
|
|
>6. COLLECTIONS OF DOCUMENTS</DT
|
|
><DD
|
|
><P
|
|
>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.</P
|
|
><P
|
|
>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.</P
|
|
></DD
|
|
><DT
|
|
>7. AGGREGATION WITH INDEPENDENT WORKS</DT
|
|
><DD
|
|
><P
|
|
>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.</P
|
|
><P
|
|
>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.</P
|
|
></DD
|
|
><DT
|
|
>8. TRANSLATION</DT
|
|
><DD
|
|
><P
|
|
>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.</P
|
|
></DD
|
|
><DT
|
|
>9. TERMINATION</DT
|
|
><DD
|
|
><P
|
|
>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.</P
|
|
></DD
|
|
><DT
|
|
>10. FUTURE REVISIONS OF THIS LICENSE</DT
|
|
><DD
|
|
><P
|
|
>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 <A
|
|
HREF="http://www.gnu.org/copyleft/"
|
|
TARGET="_top"
|
|
>http://www.gnu.org/copyleft/</A
|
|
>.</P
|
|
><P
|
|
>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.</P
|
|
></DD
|
|
><DT
|
|
>How to use this License for your documents</DT
|
|
><DD
|
|
><P
|
|
>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:</P
|
|
><P
|
|
><P
|
|
CLASS="LITERALLAYOUT"
|
|
> Copyright (c) YEAR YOUR NAME.<br>
|
|
Permission is granted to copy, distribute and/or modify this document<br>
|
|
under the terms of the GNU Free Documentation License, Version 1.1<br>
|
|
or any later version published by the Free Software Foundation;<br>
|
|
with the Invariant Sections being LIST THEIR TITLES, with the<br>
|
|
Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST.<br>
|
|
A copy of the license is included in the section entitled "GNU<br>
|
|
Free Documentation License".</P
|
|
></P
|
|
><P
|
|
>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.</P
|
|
><P
|
|
>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.</P
|
|
></DD
|
|
></DL
|
|
></DIV
|
|
></P
|
|
></DIV
|
|
></DIV
|
|
></BODY
|
|
></HTML
|
|
> |