home *** CD-ROM | disk | FTP | other *** search
/ PC World 1999 August / PCWorld_1999-08_cd.bin / doc / HOWTO / Assembly-HOWTO < prev    next >
Text File  |  1999-06-06  |  58KB  |  1,651 lines

  1.   Assembly HOWTO
  2.   Franτois-RenΘ Rideau fare@tunes.org
  3.   v0.4p, 6 June 1999
  4.  
  5.   This is the Linux Assembly HOWTO.  This document describes how to pro¡
  6.   gram in assembly using FREE programming tools, focusing on development
  7.   for or from the Linux Operating System on i386 platforms.  Included
  8.   material may or may not be applicable to other hardware and/or soft¡
  9.   ware platforms.  Contributions about these would be gladly accepted.
  10.   keywords: assembly, assembler, free, macroprocessor, preprocessor,
  11.   asm, inline asm, 32-bit, x86, i386, gas, as86, nasm
  12.   ______________________________________________________________________
  13.  
  14.   Table of Contents
  15.  
  16.  
  17.  
  18.  
  19.  
  20.  
  21.  
  22.  
  23.  
  24.  
  25.  
  26.  
  27.  
  28.  
  29.  
  30.  
  31.  
  32.  
  33.  
  34.  
  35.  
  36.  
  37.  
  38.  
  39.  
  40.  
  41.  
  42.  
  43.  
  44.  
  45.  
  46.  
  47.  
  48.  
  49.  
  50.  
  51.  
  52.  
  53.  
  54.  
  55.  
  56.  
  57.  
  58.  
  59.  
  60.  
  61.  
  62.  
  63.  
  64.  
  65.  
  66.  
  67.   1. INTRODUCTION
  68.  
  69.      1.1 Legal Blurp
  70.      1.2 Important Note
  71.      1.3 Foreword
  72.         1.3.1 How to use this document
  73.         1.3.2 Other related documents
  74.      1.4 History
  75.      1.5 Credits
  76.  
  77.   2. DO YOU NEED ASSEMBLY?
  78.  
  79.      2.1 Pros and Cons
  80.         2.1.1 The advantages of Assembly
  81.         2.1.2 The disadvantages of Assembly
  82.         2.1.3 Assessment
  83.      2.2 How to NOT use Assembly
  84.         2.2.1 General procedure to achieve efficient code
  85.         2.2.2 Languages with optimizing compilers
  86.         2.2.3 General procedure to speed your code up
  87.         2.2.4 Inspecting compiler-generated code
  88.  
  89.   3. ASSEMBLERS
  90.  
  91.      3.1 GCC Inline Assembly
  92.         3.1.1 Where to find GCC
  93.         3.1.2 Where to find docs for GCC Inline Asm
  94.         3.1.3 Invoking GCC to have it properly inline assembly code ?
  95.      3.2 GAS
  96.         3.2.1 Where to find it
  97.         3.2.2 What is this AT&T syntax
  98.         3.2.3 Limited 16-bit mode
  99.      3.3 GASP
  100.         3.3.1 Where to find GASP
  101.         3.3.2 How it works
  102.      3.4 NASM
  103.         3.4.1 Where to find NASM
  104.         3.4.2 What it does
  105.      3.5 AS86
  106.         3.5.1 Where to get AS86
  107.         3.5.2 How to invoke the assembler?
  108.         3.5.3 Where to find docs
  109.         3.5.4 What if I can't compile Linux anymore with this new version ?
  110.      3.6 OTHER ASSEMBLERS
  111.         3.6.1 Win32Forth assembler
  112.         3.6.2 Terse
  113.         3.6.3 Non-free and/or Non-32bit x86 assemblers.
  114.  
  115.   4. METAPROGRAMMING/MACROPROCESSING
  116.  
  117.      4.1 What's integrated into the above
  118.         4.1.1 GCC
  119.         4.1.2 GAS
  120.         4.1.3 GASP
  121.         4.1.4 NASM
  122.         4.1.5 AS86
  123.         4.1.6 OTHER ASSEMBLERS
  124.      4.2 External Filters
  125.         4.2.1 CPP
  126.         4.2.2 M4
  127.         4.2.3 Macroprocessing with yer own filter
  128.         4.2.4 Metaprogramming
  129.            4.2.4.1 Backends from compilers
  130.            4.2.4.2 The New-Jersey Machine-Code Toolkit
  131.            4.2.4.3 TUNES
  132.  
  133.   5. CALLING CONVENTIONS
  134.  
  135.      5.1 Linux
  136.         5.1.1 Linking to GCC
  137.         5.1.2 ELF vs a.out problems
  138.         5.1.3 Direct Linux syscalls
  139.         5.1.4 I/O under Linux
  140.         5.1.5 Accessing 16-bit drivers from Linux/i386
  141.      5.2 DOS
  142.      5.3 Winblows and suches
  143.      5.4 Yer very own OS
  144.  
  145.   6. TODO & POINTERS
  146.  
  147.  
  148.  
  149.   ______________________________________________________________________
  150.  
  151.   1.  INTRODUCTION
  152.  
  153.   1.1.  Legal Blurp
  154.  
  155.   Copyright ⌐ 1996-1999 by Franτois-RenΘ Rideau.
  156.  
  157.   This document is free software; you can redistribute it and/or modify
  158.   it under the terms of the GNU General Public License as published by
  159.   the Free Software Foundation; either version 2 of the License, or (at
  160.   your option) any later version.
  161.  
  162.  
  163.  
  164.   1.2.  Important Note
  165.  
  166.   This is an interactively evolving document: you are especially invited
  167.   to ask questions, to answer to questions, to correct given answers, to
  168.   add new FAQ answers, to give pointers to other software, to point the
  169.   current maintainer to bugs or deficiencies in the pages.  If you're
  170.   motivated, you could even take over the maintenance of the HOWTO.  In
  171.   one word, contribute!
  172.  
  173.   To contribute, please contact whoever appears to maintain the
  174.   Assembly-HOWTO. At the time of this writing, it's me, i.e.  Franτois-
  175.   RenΘ Rideau <mailto:fare@tunes.org>.
  176.  
  177.   However, it's been some time since I've been looking for a serious
  178.   hacker to replace me as maintainer of this document. Disadvantages are
  179.   you must spend some time updating and correcting the document, and
  180.   learning the LDP publication tools. Advantages are you get some fame
  181.   and you can receive complimentary copies of HOWTO compendiums.
  182.  
  183.  
  184.  
  185.   1.3.  Foreword
  186.  
  187.   This document aims at answering frequently asked questions of people
  188.   who program or want to program 32-bit x86 assembly using free
  189.   software, particularly under the Linux operating system.  It may also
  190.   point to other documents about non-free, non-x86, or non-32-bit
  191.   assemblers, though such is not its primary goal.
  192.  
  193.   Because the main interest of assembly programming is to build to write
  194.   the guts of operating systems, interpreters, compilers, and games,
  195.   where a C compiler fails to provide the needed expressiveness
  196.   (performance is more and more seldom an issue), we stress on
  197.   development of such software.
  198.  
  199.   1.3.1.  How to use this document
  200.  
  201.   This document contains answers to some frequently asked questions.  At
  202.   many places, Universal Resource Locators (URL) are given for some
  203.   software or documentation repository.  Please see that the most useful
  204.   repositories are mirrored, and that by accessing a nearer mirror site,
  205.   you relieve the whole Internet from unneeded network traffic, while
  206.   saving your own precious time.  Particularly, there are large
  207.   repositories all over the world, that mirror other popular
  208.   repositories.  You should learn and note what are those places near
  209.   you (networkwise).  Sometimes, the list of mirrors is listed in a
  210.   file, or in a login message. Please heed the advice.  Else, you should
  211.   ask archie about the software you're looking for...
  212.  
  213.   The most recent version for this documents sits in
  214.   <http://www.tunes.org/~fare/files/asm/Assembly-HOWTO.en.sgml> but
  215.   what's in Linux HOWTO repositories should be fairly up to date, too (I
  216.   can't know): <http://metalab.unc.edu/LDP/HOWTO/>.  A french
  217.   translation of this HOWTO can be found around
  218.   <ftp://ftp.lip6.fr/pub/linux/french/HOWTO/>.
  219.  
  220.  
  221.  
  222.   1.3.2.  Other related documents
  223.  
  224.  
  225.   ╖  If you don't know what free software is, please do read carefully
  226.      the GNU General Public License, which is used in a lot of free
  227.      software, and is a model for most of their licenses.  It generally
  228.      comes in a file named COPYING, with a library version in a file
  229.      named COPYING.LIB.  Literature from the FSF <http://www.fsf.org>
  230.      (free software foundation) might help you, too.
  231.  
  232.   ╖  Particularly, the interesting kind of free software comes with
  233.      sources that you can consult and correct, or sometimes even borrow
  234.      from.  Read your particular license carefully, and do comply to it.
  235.  
  236.   ╖  There is a FAQ for comp.lang.asm.x86 that answers generic questions
  237.      about x86 assembly programming, and questions about some commercial
  238.      assemblers in a 16-bit DOS environment.  Some of it apply to free
  239.      32-bit asm programming, so you may want to read this FAQ...
  240.  
  241.      <http://www2.dgsys.com/~raymoon/faq/asmfaq.zip>
  242.  
  243.   ╖  FAQs and docs exist about programming on your favorite platform,
  244.      whichever it is, that you should consult for platform-specific
  245.      issues not directly related to programming in assembler.
  246.  
  247.  
  248.  
  249.   1.4.  History
  250.  
  251.   Each version includes a few fixes and minor corrections, which needs
  252.   not be repeatedly mentionned every time.
  253.  
  254.      Version 0.1     23 Apr 1996
  255.         Francois-Rene "FarΘ" Rideau <fare@tunes.org> creates and
  256.         publishes the first mini-HOWTO, because ``I'm sick of answering
  257.         ever the same questions on comp.lang.asm.x86''
  258.  
  259.      Version 0.2     4 May 1996
  260.         *
  261.  
  262.      Version 0.3c    15 Jun 1996
  263.         *
  264.  
  265.      Version 0.3f    17 Oct 1996
  266.         *
  267.  
  268.      Version 0.3g    2 Nov 1996
  269.         Created the History. Added pointers in cross-compiling section.
  270.         Added section about I/O programming under Linux (particularly
  271.         video).
  272.  
  273.      Version 0.3h    6 Nov 1996
  274.         more about cross-compiling -- See on sunsite: devel/msdos/
  275.  
  276.      Version 0.3i    16 Nov 1996
  277.         NASM is getting pretty slick
  278.  
  279.      Version 0.3j    24 Nov 1996
  280.         point to french translated version
  281.  
  282.      Version 0.3k    19 Dec 1996
  283.         What? I had forgotten to point to terse???
  284.  
  285.      Version 0.3l    11 Jan 1997
  286.         *
  287.  
  288.      Version 0.4pre1 13 Jan 1997
  289.         text mini-HOWTO transformed into a full linuxdoc-sgml HOWTO, to
  290.         see what the SGML tools are like.
  291.  
  292.      Version 0.4     20 Jan 1997
  293.         first release of the HOWTO as such.
  294.  
  295.      Version 0.4a    20 Jan 1997
  296.         CREDITS section added
  297.  
  298.      Version 0.4b    3 Feb 1997
  299.         NASM moved: now is before AS86
  300.  
  301.      Version 0.4c    9 Feb 1997
  302.         Added section "DO YOU NEED ASSEMBLY?"
  303.  
  304.      Version 0.4d    28 Feb 1997
  305.         Vapor announce of a new Assembly-HOWTO maintainer.
  306.  
  307.      Version 0.4e    13 Mar 1997
  308.         Release for DrLinux
  309.  
  310.      Version 0.4f    20 Mar 1997
  311.         *
  312.  
  313.      Version 0.4g    30 Mar 1997
  314.         *
  315.  
  316.      Version 0.4h    19 Jun 1997
  317.         still more on "how not to use assembly"; updates on NASM, GAS.
  318.  
  319.      Version 0.4i    17 July 1997
  320.         info on 16-bit mode access from Linux.
  321.  
  322.      Version 0.4j    7 September 1997
  323.         *
  324.  
  325.      Version 0.4k    19 October 1997
  326.         *
  327.  
  328.      Version 0.4l    16 November 1997
  329.         release for LSL 6th edition.
  330.  
  331.      Version 0.4m    23 March 1998
  332.         corrections about gcc invocation
  333.  
  334.      Version 0.4o    1 December 1998
  335.         *
  336.  
  337.      Version 0.4p    6 June 1999
  338.         clean up and updates.
  339.  
  340.         This is yet another ``last release by FarΘ before new maintainer
  341.         takes over''.  Only nobody knows who the new maintainer might
  342.         be.
  343.  
  344.  
  345.  
  346.  
  347.  
  348.   1.5.  Credits
  349.  
  350.   I would like to thanks the following persons, by order of appearance:
  351.  
  352.   ╖  Linus Torvalds <mailto:buried.alive@in.mail> for Linux
  353.  
  354.   ╖  Bruce Evans <mailto:bde@zeta.org.au> for bcc from which as86 is
  355.      extracted
  356.  
  357.   ╖  Simon Tatham <mailto:anakin@pobox.com> and Julian Hall
  358.      <mailto:jules@earthcorp.com> for NASM
  359.  
  360.   ╖  Greg Hankins <mailto:gregh@metalab.unc.edu> and now Tim Bynum
  361.      <mailto:linux-howto@metalab.unc.edu> for maintaining HOWTOs
  362.  
  363.   ╖  Raymond Moon <mailto:raymoon@moonware.dgsys.com> for his FAQ
  364.  
  365.   ╖  Eric Dumas <mailto:dumas@linux.eu.org> for his translation of the
  366.      mini-HOWTO into french (sad thing for the original author to be
  367.      french and write in english)
  368.  
  369.   ╖  Paul Anderson <mailto:paul@geeky1.ebtech.net> and Rahim Azizarab
  370.      <mailto:rahim@megsinet.net> for helping me, if not for taking over
  371.      the HOWTO.
  372.  
  373.   ╖  Marc Lehman <mailto:pcg@goof.com> for his insight on GCC
  374.      invocation.
  375.  
  376.   ╖  All the people who have contributed ideas, remarks, and moral
  377.      support.
  378.  
  379.  
  380.  
  381.  
  382.   2.  DO YOU NEED ASSEMBLY?
  383.  
  384.   Well, I wouldn't want to interfere with what you're doing, but here
  385.   are a few advice from hard-earned experience.
  386.  
  387.  
  388.  
  389.   2.1.  Pros and Cons
  390.  
  391.  
  392.  
  393.   2.1.1.  The advantages of Assembly
  394.  
  395.   Assembly can express very low-level things:
  396.  
  397.   ╖  you can access machine-dependent registers and I/O.
  398.  
  399.   ╖  you can control the exact behavior of code in critical sections
  400.      that might otherwise involve deadlock between multiple software
  401.      threads or hardware devices.
  402.  
  403.   ╖  you can break the conventions of your usual compiler, which might
  404.      allow some optimizations (like temporarily breaking rules about
  405.      memory allocation, threading, calling conventions, etc).
  406.  
  407.   ╖  you can build interfaces between code fragments using incompatible
  408.      such conventions (e.g. produced by different compilers, or
  409.      separated by a low-level interface).
  410.  
  411.   ╖  you can get access to unusual programming modes of your processor
  412.      (e.g. 16 bit mode to interface startup, firmware, or legacy code on
  413.      Intel PCs)
  414.  
  415.   ╖  you can produce reasonably fast code for tight loops to cope with a
  416.      bad non-optimizing compiler (but then, there are free optimizing
  417.      compilers available!)
  418.  
  419.   ╖  you can produce code where (but only on CPUs with known instruction
  420.      timings, which generally excludes all current ....
  421.  
  422.   ╖  you can produce hand-optimized code that's perfectly tuned for your
  423.      particular hardware setup, though not to anyone else's.
  424.  
  425.   ╖  you can write some code for your new language's optimizing compiler
  426.      (that's something few will ever do, and even they, not often).
  427.  
  428.  
  429.  
  430.  
  431.   2.1.2.  The disadvantages of Assembly
  432.  
  433.   Assembly is a very low-level language (the lowest above hand-coding
  434.   the binary instruction patterns).  This means
  435.  
  436.   ╖  it's long and tedious to write initially,
  437.  
  438.   ╖  it's very bug-prone,
  439.  
  440.   ╖  your bugs will be very difficult to chase,
  441.  
  442.   ╖  it's very difficult to understand and modify, i.e. to maintain.
  443.  
  444.   ╖  the result is very non-portable to other architectures, existing or
  445.      future,
  446.  
  447.   ╖  your code will be optimized only for a certain implementation of a
  448.      same architecture: for instance, among Intel-compatible platforms,
  449.      each CPU design and its variations (relative latency, throughput,
  450.      and capacity, of processing units, caches, RAM, bus, disks,
  451.      presence of FPU, MMX extensions, etc) implies potentially
  452.      completely different optimization techniques.  CPU designs already
  453.      include Intel 386, 486, Pentium, PPro, Pentium II; Cyrix 5x86,
  454.      6x86; AMD K5, K6.  New designs keep popping up, so don't expect
  455.      either this listing or your code to be up-to-date.
  456.  
  457.   ╖  your code might also be unportable accross different OS platforms
  458.      on the same architecture, by lack of proper tools.  (well, GAS
  459.      seems to work on all platforms; NASM seems to work or be workable
  460.      on all intel platforms).
  461.  
  462.  
  463.   ╖  you spend more time on a few details, and can't focus on small and
  464.      large algorithmic design, that are known to bring the largest part
  465.      of the speed up.  [e.g. you might spend some time building very
  466.      fast list/array manipulation primitives in assembly; only a hash
  467.      table would have sped up your program much more; or, in another
  468.      context, a binary tree; or some high-level structure distributed
  469.      over a cluster of CPUs]
  470.  
  471.   ╖  a small change in algorithmic design might completely invalidate
  472.      all your existing assembly code.  So that either you're ready (and
  473.      able) to rewrite it all, or you're tied to a particular algorithmic
  474.      design;
  475.  
  476.   ╖  On code that ain't too far from what's in standard benchmarks,
  477.      commercial optimizing compilers outperform hand-coded assembly
  478.      (well, that's less true on the x86 architecture than on RISC
  479.      architectures, and perhaps less true for widely available/free
  480.      compilers; anyway, for typical C code, GCC is fairly good);
  481.  
  482.   ╖  And in any case, as says moderator John Levine on comp.compilers,
  483.      ``compilers make it a lot easier to use complex data structures,
  484.      and compilers don't get bored halfway through and generate reliably
  485.      pretty good code.''  They will also correctly propagate code
  486.      transformations throughout the whole (huge) program when optimizing
  487.      code between procedures and module boundaries.
  488.  
  489.  
  490.  
  491.   2.1.3.  Assessment
  492.  
  493.   All in all, you might find that though using assembly is sometimes
  494.   needed, and might even be useful in a few cases where it is not,
  495.   you'll want to:
  496.  
  497.   ╖  minimize the use of assembly code,
  498.  
  499.   ╖  encapsulate this code in well-defined interfaces
  500.  
  501.   ╖  have your assembly code automatically generated from patterns
  502.      expressed in a higher-level language than assembly (e.g. GCC inline
  503.      assembly macros).
  504.  
  505.   ╖  have automatic tools translate these programs into assembly code
  506.  
  507.   ╖  have this code be optimized if possible
  508.  
  509.   ╖  All of the above, i.e. write (an extension to) an optimizing
  510.      compiler back-end.
  511.  
  512.   Even in cases when Assembly is needed (e.g. OS development), you'll
  513.   find that not so much of it is, and that the above principles hold.
  514.  
  515.   See the sources for the Linux kernel about it: as little assembly as
  516.   needed, resulting in a fast, reliable, portable, maintainable OS.
  517.   Even a successful game like DOOM was almost massively written in C,
  518.   with a tiny part only being written in assembly for speed up.
  519.  
  520.  
  521.  
  522.   2.2.  How to NOT use Assembly
  523.  
  524.  
  525.  
  526.  
  527.  
  528.  
  529.   2.2.1.  General procedure to achieve efficient code
  530.  
  531.   As says Charles Fiterman on comp.compilers about human vs computer-
  532.   generated assembly code,
  533.  
  534.   ``The human should always win and here is why.
  535.  
  536.   ╖  First the human writes the whole thing in a high level language.
  537.  
  538.   ╖  Second he profiles it to find the hot spots where it spends its
  539.      time.
  540.  
  541.   ╖  Third he has the compiler produce assembly for those small sections
  542.      of code.
  543.  
  544.   ╖  Fourth he hand tunes them looking for tiny improvements over the
  545.      machine generated code.
  546.  
  547.      The human wins because he can use the machine.''
  548.  
  549.  
  550.  
  551.   2.2.2.  Languages with optimizing compilers
  552.  
  553.   Languages like ObjectiveCAML, SML, CommonLISP, Scheme, ADA, Pascal, C,
  554.   C++, among others, all have free optimizing compilers that'll optimize
  555.   the bulk of your programs, and often do better than hand-coded
  556.   assembly even for tight loops, while allowing you to focus on higher-
  557.   level details, and without forbidding you to grab a few percent of
  558.   extra performance in the above-mentionned way, once you've reached a
  559.   stable design.  Of course, there are also commercial optimizing
  560.   compilers for most of these languages, too!
  561.  
  562.   Some languages have compilers that produce C code, which can be
  563.   further optimized by a C compiler.  LISP, Scheme, Perl, and many other
  564.   are suches.  Speed is fairly good.
  565.  
  566.  
  567.  
  568.  
  569.   2.2.3.  General procedure to speed your code up
  570.  
  571.   As for speeding code up, you should do it only for parts of a program
  572.   that a profiling tool has consistently identified as being a
  573.   performance bottleneck.
  574.  
  575.   Hence, if you identify some code portion as being too slow, you should
  576.  
  577.   ╖  first try to use a better algorithm;
  578.  
  579.   ╖  then try to compile it rather than interpret it;
  580.  
  581.   ╖  then try to enable and tweak optimization from your compiler;
  582.  
  583.   ╖  then give the compiler hints about how to optimize (typing
  584.      information in LISP; register usage with GCC; lots of options in
  585.      most compilers, etc).
  586.  
  587.   ╖  then possibly fallback to assembly programming
  588.  
  589.   Finally, before you end up writing assembly, you should inspect
  590.   generated code, to check that the problem really is with bad code
  591.   generation, as this might really not be the case: compiler-generated
  592.   code might be better than what you'd have written, particularly on
  593.   modern multi-pipelined architectures!  Slow parts of a program might
  594.   be intrinsically so.  Biggest problems on modern architectures with
  595.   fast processors are due to delays from memory access, cache-misses,
  596.   TLB-misses, and page-faults; register optimization becomes useless,
  597.   and you'll more profitably re-think data structures and threading to
  598.   achieve better locality in memory access.  Perhaps a completely
  599.   different approach to the problem might help, then.
  600.  
  601.  
  602.  
  603.   2.2.4.  Inspecting compiler-generated code
  604.  
  605.   There are many reasons to inspect compiler-generated assembly code.
  606.   Here are what you'll do with such code:
  607.  
  608.   ╖  check whether generated code can be obviously enhanced with hand-
  609.      coded assembly (or by tweaking compiler switches)
  610.  
  611.   ╖  when that's the case, start from generated code and modify it
  612.      instead of starting from scratch
  613.  
  614.   ╖  more generally, use generated code as stubs to modify, which at
  615.      least gets right the way your assembly routines interface to the
  616.      external world
  617.  
  618.   ╖  track down bugs in your compiler (hopefully rarer)
  619.  
  620.   The standard way to have assembly code be generated is to invoke your
  621.   compiler with the -S flag.  This works with most Unix compilers,
  622.   including the GNU C Compiler (GCC), but YMMV.  As for GCC, it will
  623.   produce more understandable assembly code with the -fverbose-asm
  624.   command-line option.  Of course, if you want to get good assembly
  625.   code, don't forget your usual optimization options and hints!
  626.  
  627.  
  628.  
  629.  
  630.   3.  ASSEMBLERS
  631.  
  632.  
  633.  
  634.   3.1.  GCC Inline Assembly
  635.  
  636.   The well-known GNU C/C++ Compiler (GCC), an optimizing 32-bit compiler
  637.   at the heart of the GNU project, supports the x86 architecture quite
  638.   well, and includes the ability to insert assembly code in C programs,
  639.   in such a way that register allocation can be either specified or left
  640.   to GCC.  GCC works on most available platforms, notably Linux, *BSD,
  641.   VSTa, OS/2, *DOS, Win*, etc.
  642.  
  643.  
  644.   3.1.1.  Where to find GCC
  645.  
  646.   The original GCC site is the GNU FTP site
  647.   <ftp://prep.ai.mit.edu/pub/gnu/gcc/> together with all the released
  648.   application software from the GNU project.  Linux-configured and
  649.   precompiled versions can be found in
  650.   <ftp://metalab.unc.edu/pub/Linux/GCC/> There exists a lot of FTP
  651.   mirrors of both sites.  everywhere around the world, as well as CD-ROM
  652.   copies.
  653.  
  654.   GCC development has split in two branches recently.  See more about
  655.   the experimental version, egcs, at <http://www.cygnus.com/egcs/>
  656.  
  657.   Sources adapted to your favorite OS, and binaries precompiled for it,
  658.   should be found at your usual FTP sites.
  659.  
  660.  
  661.   For most popular DOS port of GCC is named DJGPP, and can be found in
  662.   directories of such name in FTP sites. See:
  663.  
  664.   <http://www.delorie.com/djgpp/>
  665.  
  666.  
  667.   There is also a port of GCC to OS/2 named EMX, that also works under
  668.   DOS, and includes lots of unix-emulation library routines.  See around
  669.   the following site: <ftp://ftp-os2.cdrom.com/pub/os2/emx09c/>.  Other
  670.   URLs listed in previous versions of this HOWTO seem to be as dead as
  671.   OS/2.
  672.  
  673.  
  674.   3.1.2.  Where to find docs for GCC Inline Asm
  675.  
  676.   The documentation of GCC includes documentation files in texinfo
  677.   format.  You can compile them with tex and print then result, or
  678.   convert them to .info, and browse them with emacs, or convert them to
  679.   .html, or nearly whatever you like.  convert (with the right tools) to
  680.   whatever you like, or just read as is.  The .info files are generally
  681.   found on any good installation for GCC.
  682.  
  683.   The right section to look for is: C Extensions::Extended Asm::
  684.  
  685.   Section Invoking GCC::Submodel Options::i386 Options:: might help too.
  686.   Particularly, it gives the i386 specific constraint names for
  687.   registers: abcdSDB correspond to %eax, %ebx, %ecx, %edx, %esi, %edi,
  688.   %ebp respectively (no letter for %esp).
  689.  
  690.   The DJGPP Games resource (not only for game hackers) had this page
  691.   specifically about assembly, but it's down.  Its data have nonetheless
  692.   been recovered on the DJGPP site <http://www.delorie.com/djgpp/>, that
  693.   contains a mine of other useful information:
  694.   <http://www.delorie.com/djgpp/doc/brennan/>
  695.  
  696.   GCC depends on GAS for assembling, and follow its syntax (see below);
  697.   do mind that inline asm needs percent characters to be quoted so they
  698.   be passed to GAS.  See the section about GAS below.
  699.  
  700.   Find lots of useful examples in the linux/include/asm-i386/
  701.   subdirectory of the sources for the Linux kernel.
  702.  
  703.  
  704.  
  705.  
  706.   3.1.3.  Invoking GCC to have it properly inline assembly code ?
  707.  
  708.   Because assembly routines from the kernel headers (and most likely
  709.   your own headers, if you try making your assembly programming as clean
  710.   as it is in the linux kernel) are embedded in extern inline functions,
  711.   GCC must be invoked with the -O flag (or -O2, -O3, etc), for these
  712.   routines to be available.  If not, your code may compile, but not link
  713.   properly, since it will be looking for non-inlined extern functions in
  714.   the libraries against which your program is being linked !!!  Another
  715.   way is to link against libraries that include fallback versions of the
  716.   routines.
  717.  
  718.   Inline assembly can be disabled with -fno-asm, which will have the
  719.   compiler die when using extended inline asm syntax, or else generate
  720.   calls to an external function named asm() that the linker can't
  721.   resolve.  To counter such flag, -fasm restores treatment of the asm
  722.   keyword.
  723.  
  724.   More generally, good compile flags for GCC on the x86 platform are
  725.  
  726.  
  727.   ______________________________________________________________________
  728.           gcc -O2 -fomit-frame-pointer -W -Wall
  729.   ______________________________________________________________________
  730.  
  731.  
  732.  
  733.   -O2 is the good optimization level in most cases.  Optimizing besides
  734.   it takes longer, and yields code that is a lot larger, but only a bit
  735.   faster; such overoptimization might be useful for tight loops only (if
  736.   any), which you may be doing in assembly anyway.  In cases when you
  737.   need really strong compiler optimization for a few files, do consider
  738.   using up to -O6.
  739.  
  740.   -fomit-frame-pointer allows generated code to skip the stupid frame
  741.   pointer maintenance, which makes code smaller and faster, and frees a
  742.   register for further optimizations.  It precludes the easy use of
  743.   debugging tools (gdb), but when you use these, you just don't care
  744.   about size and speed anymore anyway.
  745.  
  746.   -W -Wall enables all warnings and helps you catch obvious stupid
  747.   errors.
  748.  
  749.   You can add some cpu-specific -m486 or such flag so that GCC will
  750.   produce code that is more adapted to your precise computer.  Note that
  751.   EGCS (and perhaps GCC 2.8) have -mpentium and such flags, whereas GCC
  752.   2.7.x and older versions do not.  A good choice of CPU-specific flags
  753.   should be in the Linux kernel.  Check the texinfo documentation of
  754.   your current GCC installation for more.
  755.  
  756.   -m386 will help optimize for size, hence also for speed on computers
  757.   whose memory is tight and/or loaded, since big programs cause swap,
  758.   which more than counters any "optimization" intended by the larger
  759.   code.  In such settings, it might be useful to stop using C, and use
  760.   instead a language that favors code factorization, such as a
  761.   functional language and/or FORTH, and use a bytecode- or wordcode-
  762.   based implementation.
  763.  
  764.   Note that you can vary code generation flags from file to file, so
  765.   that performance-critical files use maximal optimization, whereas
  766.   other files be optimized for size.
  767.  
  768.   To optimize even more, option -mregparm=2 and/or corresponding
  769.   function attribute might help, but might pose lots of problems when
  770.   linking to foreign code, including the libc.  There are ways to
  771.   correctly declare foreign functions so the right call sequences be
  772.   generated, or you might want to recompile the foreign libraries to use
  773.   the same register-based calling convention...
  774.  
  775.   Note that you can add make these flags the default by editing file
  776.   /usr/lib/gcc-lib/i486-linux/2.7.2.3/specs or wherever that is on your
  777.   system (better not add -Wall there, though).  The exact location of
  778.   the GCC specs files on your system can be found by asking gcc -v.
  779.  
  780.  
  781.  
  782.   3.2.  GAS
  783.  
  784.   GAS is the GNU Assembler, that GCC relies upon.
  785.  
  786.  
  787.  
  788.   3.2.1.  Where to find it
  789.  
  790.   Find it at the same place where you found GCC, in a package named
  791.   binutils.
  792.  
  793.   3.2.2.  What is this AT&T syntax
  794.  
  795.   Because GAS was invented to support a 32-bit unix compiler, it uses
  796.   standard ``AT&T'' syntax, which resembles a lot the syntax for
  797.   standard m68k assemblers, and is standard in the UNIX world.  This
  798.   syntax is no worse, no better than the ``Intel'' syntax.  It's just
  799.   different.  When you get used to it, you find it much more regular
  800.   than the Intel syntax, though a bit boring.
  801.  
  802.   Here are the major caveats about GAS syntax:
  803.  
  804.   ╖  Register names are prefixed with %, so that registers are %eax, %dl
  805.      and suches instead of just eax, dl, etc.  This makes it possible to
  806.      include external C symbols directly in assembly source, without any
  807.      risk of confusion, or any need for ugly underscore prefixes.
  808.  
  809.   ╖  The order of operands is source(s) first, and destination last, as
  810.      opposed to the intel convention of destination first and sources
  811.      last.  Hence, what in intel syntax is mov ax,dx (move contents of
  812.      register dx into register ax) will be in att syntax mov %dx, %ax.
  813.  
  814.   ╖  The operand length is specified as a suffix to the instruction
  815.      name.  The suffix is b for (8-bit) byte, w for (16-bit) word, and l
  816.      for (32-bit) long.  For instance, the correct syntax for the above
  817.      instruction would have been movw %dx,%ax.  However, gas does not
  818.      require strict att syntax, so the suffix is optional when length
  819.      can be guessed from register operands, and else defaults to 32-bit
  820.      (with a warning).
  821.  
  822.   ╖  Immediate operands are marked with a $ prefix, as in addl $5,%eax
  823.      (add immediate long value 5 to register %eax).
  824.  
  825.   ╖  No prefix to an operand indicates it is a memory-address; hence
  826.      movl $foo,%eax puts the address of variable foo in register %eax,
  827.      but movl foo,%eax puts the contents of variable foo in register
  828.      %eax.
  829.  
  830.   ╖  Indexing or indirection is done by enclosing the index register or
  831.      indirection memory cell address in parentheses, as in testb
  832.      $0x80,17(%ebp) (test the high bit of the byte value at offset 17
  833.      from the cell pointed to by %ebp).
  834.  
  835.  
  836.   A program exists to help you convert programs from TASM syntax to AT&T
  837.   syntax. See
  838.   <ftp://x2ftp.oulu.fi/pub/msdos/programming/convert/ta2asv08.zip>.
  839.   (Since the original x2ftp site is closing, use a mirror site
  840.   <ftp://ftp.lip6.fr/pub/pc/x2ftp/README.mirror_sites>).  There also
  841.   exists a program for the reverse conversion:
  842.   <http://www.multimania.com/placr/a2i.html>.
  843.  
  844.  
  845.   GAS has comprehensive documentation in TeXinfo format, which comes at
  846.   least with the source distribution.  Browse extracted .info pages with
  847.   Emacs or whatever.  There used to be a file named gas.doc or as.doc
  848.   around the GAS source package, but it was merged into the TeXinfo
  849.   docs.  Of course, in case of doubt, the ultimate documentation is the
  850.   sources themselves!  A section that will particularly interest you is
  851.   Machine Dependencies::i386-Dependent::
  852.  
  853.  
  854.   Again, the sources for Linux (the OS kernel), come in as good
  855.   examples; see under linux/arch/i386, the following files: kernel/*.S,
  856.   boot/compressed/*.S, mathemu/*.S
  857.  
  858.  
  859.   If you are writing kind of a language, a thread package, etc you might
  860.   as well see how other languages (OCaml, gforth, etc), or thread
  861.   packages (QuickThreads, MIT pthreads, LinuxThreads, etc), or whatever,
  862.   do it.
  863.  
  864.   Finally, just compiling a C program to assembly might show you the
  865.   syntax for the kind of instructions you want.  See section ``Do you
  866.   need Assembly?'' above.
  867.  
  868.  
  869.  
  870.  
  871.   3.2.3.  Limited 16-bit mode
  872.  
  873.   GAS is a 32-bit assembler, meant to support a 32-bit compiler.  It
  874.   currently has only limited support for 16-bit mode, which consists in
  875.   prepending the 32-bit prefixes to instructions, so you write 32-bit
  876.   code that runs in 16-bit mode on a 32 bit CPU.  In both modes, it
  877.   supports 16-bit register usage, but what is unsupported is 16-bit
  878.   addressing.  Use the directive .code16 and .code32 to switch between
  879.   modes.  Note that an inline assembly statement asm(".code16\n") will
  880.   allow GCC to produce 32-bit code that'll run in real mode!
  881.  
  882.   I've been told that most code needed to fully support 16-bit mode
  883.   programming was added to GAS by Bryan Ford (please confirm?), but at
  884.   least, it doesn't show up in any of the distribution I tried, up to
  885.   binutils-2.8.1.x ... more info on this subject would be welcome.
  886.  
  887.   A cheap solution is to define macros (see below) that somehow produce
  888.   the binary encoding (with .byte) for just the 16-bit mode instructions
  889.   you need (almost nothing if you use code16 as above, and can safely
  890.   assume the code will run on a 32-bit capable x86 CPU).  To find the
  891.   proper encoding, you can get inspiration from the sources of 16-bit
  892.   capable assemblers for the encoding.
  893.  
  894.  
  895.  
  896.   3.3.  GASP
  897.  
  898.   GASP is the GAS Preprocessor.  It adds macros and some nice syntax to
  899.   GAS.
  900.  
  901.  
  902.  
  903.   3.3.1.  Where to find GASP
  904.  
  905.   GASP comes together with GAS in the GNU binutils archive.
  906.  
  907.  
  908.  
  909.   3.3.2.  How it works
  910.  
  911.   It works as a filter, much like cpp and the like.  I have no idea on
  912.   details, but it comes with its own texinfo documentation, so just
  913.   browse them (in .info), print them, grok them.  GAS with GASP looks
  914.   like a regular macro-assembler to me.
  915.  
  916.  
  917.  
  918.   3.4.  NASM
  919.  
  920.   The Netwide Assembler project is producing yet another i386 assembler,
  921.   written in C, that should be modular enough to eventually support all
  922.   known syntaxes and object formats.
  923.  
  924.  
  925.   3.4.1.  Where to find NASM
  926.  
  927.   <http://www.cryogen.com/Nasm>
  928.  
  929.   Binary release on your usual metalab mirror in devel/lang/asm/ Should
  930.   also be available as .rpm or .deb in your usual RedHat/Debian
  931.   distributions' contrib.
  932.  
  933.  
  934.   3.4.2.  What it does
  935.  
  936.   At the time this HOWTO is written, version 0.98 of NASM is just out.
  937.  
  938.   The syntax is Intel-style.  Some macroprocessing support is
  939.   integrated.
  940.  
  941.   Supported object file formats are bin, aout, coff, elf, as86, (DOS)
  942.   obj, win32, (their own format) rdf.
  943.  
  944.   NASM can be used as a backend for the free LCC compiler (support files
  945.   included).
  946.  
  947.  
  948.   Surely NASM evolves too fast for this HOWTO to be kept up to date.
  949.   Unless you're using BCC as a 16-bit compiler (which is out of scope of
  950.   this 32-bit HOWTO), you should definitely use NASM instead of say AS86
  951.   or MASM, because it is actively supported online, and runs on all
  952.   platforms.
  953.  
  954.   Note: NASM also comes with a disassembler, NDISASM.
  955.  
  956.   Its hand-written parser makes it much faster than GAS, though of
  957.   course, it doesn't support three bazillion different architectures.
  958.   For the x86 target, it should be the assembler of choice...
  959.  
  960.  
  961.  
  962.   3.5.  AS86
  963.  
  964.   AS86 is a 80x86 assembler, both 16-bit and 32-bit, part of Bruce
  965.   Evans' C Compiler (BCC).  It has mostly Intel-syntax, though it
  966.   differs slightly as for addressing modes.
  967.  
  968.  
  969.  
  970.   3.5.1.  Where to get AS86
  971.  
  972.   A completely outdated version of AS86 is distributed by HJLu just to
  973.   compile the Linux kernel, in a package named bin86 (current version
  974.   0.4), available in any Linux GCC repository.  But I advise no one to
  975.   use it for anything else but compiling Linux.  This version supports
  976.   only a hacked minix object file format, which is not supported by the
  977.   GNU binutils or anything, and it has a few bugs in 32-bit mode, so you
  978.   really should better keep it only for compiling Linux.
  979.  
  980.   The most recent versions by Bruce Evans (bde@zeta.org.au) are
  981.   published together with the FreeBSD distribution.  Well, they were: I
  982.   could not find the sources from distribution 2.1 on :( Hence, I put
  983.   the sources at my place:
  984.   <http://www.tunes.org/~fare/files/asm/bcc-95.3.12.src.tgz>
  985.  
  986.   The Linux/8086 (aka ELKS) project is somehow maintaining bcc (though I
  987.   don't think they included the 32-bit patches).  See around
  988.   <http://www.linux.org.uk/ELKS-Home/index.html> and
  989.   <ftp://linux.mit.edu/pub/linux/ELKS/>.  I haven't followed these
  990.   developments, and would appreciate a reader contributing on this
  991.   topic.
  992.  
  993.   Among other things, these more recent versions, unlike HJLu's,
  994.   supports Linux GNU a.out format, so you can link you code to Linux
  995.   programs, and/or use the usual tools from the GNU binutils package to
  996.   manipulate your data.  This version can co-exist without any harm with
  997.   the previous one (see according question below).
  998.  
  999.   BCC from 12 march 1995 and earlier version has a misfeature that makes
  1000.   all segment pushing/popping 16-bit, which is quite annoying when
  1001.   programming in 32-bit mode.  I wrote a patch at a time when the TUNES
  1002.   Project used as86:
  1003.   <http://www.tunes.org/~fare/files/asm/as86.bcc.patch.gz>.  Bruce Evans
  1004.   accepted this patch, but since as far as I know he hasn't published a
  1005.   new release of bcc, the ones to ask about integrating it (if not done
  1006.   yet) are the ELKS developers.
  1007.  
  1008.  
  1009.  
  1010.   3.5.2.  How to invoke the assembler?
  1011.  
  1012.   Here's the GNU Makefile entry for using bcc to transform .s asm into
  1013.   both GNU a.out .o object and .l listing:
  1014.  
  1015.  
  1016.   ______________________________________________________________________
  1017.   %.o %.l:        %.s
  1018.           bcc -3 -G -c -A-d -A-l -A$*.l -o $*.o $<
  1019.   ______________________________________________________________________
  1020.  
  1021.  
  1022.  
  1023.   Remove the %.l, -A-l, and -A$*.l, if you don't want any listing.  If
  1024.   you want something else than GNU a.out, you can see the docs of bcc
  1025.   about the other supported formats, and/or use the objcopy utility from
  1026.   the GNU binutils package.
  1027.  
  1028.  
  1029.  
  1030.   3.5.3.  Where to find docs
  1031.  
  1032.   The docs are what is included in the bcc package.  I salvaged the man
  1033.   pages that used to be available from the FreeBSD site at
  1034.   <http://www.tunes.org/~fare/files/asm/bcc-95.3.12.src.tgz>.  Maybe
  1035.   ELKS developers know better.  When in doubt, the sources themselves
  1036.   are often a good docs: it's not very well commented, but the
  1037.   programming style is straightforward.  You might try to see how as86
  1038.   is used in ELKS or Tunes 0.0.0.25...
  1039.  
  1040.  
  1041.  
  1042.   3.5.4.  What if I can't compile Linux anymore with this new version ?
  1043.  
  1044.   Linus is buried alive in mail, and since HJLu (official bin86
  1045.   maintainer) chose to write hacks around an obsolete version of as86
  1046.   instead of building clean code around the latest version, I don't
  1047.   think my patch for compiling Linux with a modern as86 has any chance
  1048.   to be accepted if resubmitted.  Now, this shouldn't matter: just keep
  1049.   your as86 from the bin86 package in /usr/bin, and let bcc install the
  1050.   good as86 as /usr/local/libexec/i386/bcc/as where it should be. You
  1051.   never need explicitly call this ``good'' as86, because bcc does
  1052.   everything right, including conversion to Linux a.out, when invoked
  1053.   with the right options; so assemble files exclusively with bcc as a
  1054.   frontend, not directly with as86.
  1055.  
  1056.  
  1057.   3.6.  OTHER ASSEMBLERS
  1058.  
  1059.   These are other, non-regular, options, in case the previous didn't
  1060.   satisfy you (why?), that I don't recommend in the usual (?) case, but
  1061.   that could prove quite useful if the assembler must be integrated in
  1062.   the software you're designing (i.e. an OS or development environment).
  1063.  
  1064.  
  1065.  
  1066.   3.6.1.  Win32Forth assembler
  1067.  
  1068.   Win32Forth is a free 32-bit ANS FORTH system that successfully runs
  1069.   under Win32s, Win95, Win/NT.  It includes a free 32-bit assembler
  1070.   (either prefix or postfix syntax) integrated into the reflective FORTH
  1071.   language.  Macro processing is done with the full power of the
  1072.   reflective language FORTH; however, the only supported input and
  1073.   output contexts is Win32For itself (no dumping of .obj file, but you
  1074.   could add that feature yourself, of course).  Find it at
  1075.   <ftp://ftp.forth.org/pub/Forth/Compilers/native/windows/Win32For/>.
  1076.  
  1077.  
  1078.  
  1079.   3.6.2.  Terse
  1080.  
  1081.   Terse is a programming tool that provides THE most compact assembler
  1082.   syntax for the x86 family!  See  <http://www.terse.com>.  However, it
  1083.   is not quite free software.  It is said that there was a project for a
  1084.   free clone somewhere, that was abandonned after worthless pretenses
  1085.   that the syntax would be owned by the original author.  Thus, if
  1086.   you're looking for a nifty programming project related to assembly
  1087.   hacking, I invite you to develop a terse-syntax frontend to NASM, if
  1088.   you like that syntax.
  1089.  
  1090.  
  1091.  
  1092.   3.6.3.  Non-free and/or Non-32bit x86 assemblers.
  1093.  
  1094.   You may find more about them, together with the basics of x86 assembly
  1095.   programming, in Raymond Moon's FAQ for comp.lang.asm.x86:
  1096.   <http://www2.dgsys.com/~raymoon/faq/asmfaq.zip>.
  1097.  
  1098.   Note that all DOS-based assemblers should work inside the Linux DOS
  1099.   Emulator, as well as other similar emulators, so that if you already
  1100.   own one, you can still use it inside a real OS.  Recent DOS-based
  1101.   assemblers also support COFF and/or other object file formats that are
  1102.   supported by the GNU BFD library, so that you can use them together
  1103.   with your free 32-bit tools, perhaps using GNU objcopy (part of the
  1104.   binutils) as a conversion filter.
  1105.  
  1106.  
  1107.  
  1108.  
  1109.   4.  METAPROGRAMMING/MACROPROCESSING
  1110.  
  1111.   Assembly programming is a bore, but for critical parts of programs.
  1112.  
  1113.   You should use the appropriate tool for the right task, so don't
  1114.   choose assembly when it's not fit; C, OCAML, perl, Scheme, might be a
  1115.   better choice for most of your programming.
  1116.  
  1117.   However, there are cases when these tools do not give a fine enough
  1118.   control on the machine, and assembly is useful or needed.  In those
  1119.   case, you'll appreciate a system of macroprocessing and
  1120.   metaprogramming that'll allow recurring patterns to be factored each
  1121.   into a one indefinitely reusable definition, which allows safer
  1122.   programming, automatic propagation of pattern modification, etc.  A
  1123.   ``plain'' assembler is often not enough, even when one is doing only
  1124.   small routines to link with C.
  1125.  
  1126.  
  1127.  
  1128.   4.1.  What's integrated into the above
  1129.  
  1130.  
  1131.   Yes I know this section does not contain much useful up-to-date
  1132.   information.  Feel free to contribute what you discover the hard
  1133.   way...
  1134.  
  1135.  
  1136.  
  1137.   4.1.1.  GCC
  1138.  
  1139.   GCC allows (and requires) you to specify register constraints in your
  1140.   ``inline assembly'' code, so the optimizer always know about it; thus,
  1141.   inline assembly code is really made of patterns, not forcibly exact
  1142.   code.
  1143.  
  1144.   Thus, you can make put your assembly into CPP macros, and inline C
  1145.   functions, so anyone can use it in as any C function/macro.  Inline
  1146.   functions resemble macros very much, but are sometimes cleaner to use.
  1147.   Beware that in all those cases, code will be duplicated, so only local
  1148.   labels (of 1: style) should be defined in that asm code.  However, a
  1149.   macro would allow the name for a non local defined label to be passed
  1150.   as a parameter (or else, you should use additional meta-programming
  1151.   methods).  Also, note that propagating inline asm code will spread
  1152.   potential bugs in them; so watch out doubly for register constraints
  1153.   in such inline asm code.
  1154.  
  1155.   Lastly, the C language itself may be considered as a good abstraction
  1156.   to assembly programming, which relieves you from most of the trouble
  1157.   of assembling.
  1158.  
  1159.  
  1160.  
  1161.   4.1.2.  GAS
  1162.  
  1163.   GAS has some macro capability included, as detailed in the texinfo
  1164.   docs.  Moreover, while GCC recognizes .s files as raw assembly to send
  1165.   to GAS, it also recognizes .S files as files to pipe through CPP
  1166.   before to feed them to GAS.  Again and again, see Linux sources for
  1167.   examples.
  1168.  
  1169.  
  1170.  
  1171.   4.1.3.  GASP
  1172.  
  1173.   It adds all the usual macroassembly tricks to GAS.  See its texinfo
  1174.   docs.
  1175.  
  1176.  
  1177.  
  1178.   4.1.4.  NASM
  1179.  
  1180.   NASM has some macro support, too.  See according docs.  If you have
  1181.   some bright idea, you might wanna contact the authors, as they are
  1182.   actively developing it.  Meanwhile, see about external filters below.
  1183.  
  1184.  
  1185.  
  1186.  
  1187.  
  1188.  
  1189.   4.1.5.  AS86
  1190.  
  1191.   It has some simple macro support, but I couldn't find docs.  Now the
  1192.   sources are very straightforward, so if you're interested, you should
  1193.   understand them easily.  If you need more than the basics, you should
  1194.   use an external filter (see below).
  1195.  
  1196.  
  1197.  
  1198.   4.1.6.  OTHER ASSEMBLERS
  1199.  
  1200.  
  1201.   ╖  Win32FORTH: CODE and END-CODE are normal that do not switch from
  1202.      interpretation mode to compilation mode, so you have access to the
  1203.      full power of FORTH while assembling.
  1204.  
  1205.   ╖  TUNES: it doesn't work yet, but the Scheme language is a real high-
  1206.      level language that allows arbitrary meta-programming.
  1207.  
  1208.  
  1209.  
  1210.   4.2.  External Filters
  1211.  
  1212.   Whatever is the macro support from your assembler, or whatever
  1213.   language you use (even C !), if the language is not expressive enough
  1214.   to you, you can have files passed through an external filter with a
  1215.   Makefile rule like that:
  1216.  
  1217.  
  1218.   ______________________________________________________________________
  1219.   %.s:    %.S other_dependencies
  1220.           $(FILTER) $(FILTER_OPTIONS) < $< > $@
  1221.   ______________________________________________________________________
  1222.  
  1223.  
  1224.  
  1225.  
  1226.  
  1227.   4.2.1.  CPP
  1228.  
  1229.   CPP is truely not very expressive, but it's enough for easy things,
  1230.   it's standard, and called transparently by GCC.
  1231.  
  1232.   As an example of its limitations, you can't declare objects so that
  1233.   destructors are automatically called at the end of the declaring
  1234.   block; you don't have diversions or scoping, etc.
  1235.  
  1236.   CPP comes with any C compiler.  However, considering how mediocre it
  1237.   is, stay away from it if by chance you can make it without C,
  1238.  
  1239.  
  1240.  
  1241.   4.2.2.  M4
  1242.  
  1243.   M4 gives you the full power of macroprocessing, with a Turing
  1244.   equivalent language, recursion, regular expressions, etc.  You can do
  1245.   with it everything that CPP cannot.
  1246.  
  1247.   See macro4th (this4th)
  1248.   <ftp://ftp.forth.org/pub/Forth/Compilers/native/unix/this4th.tar.gz>
  1249.   or the Tunes 0.0.0.25 sources
  1250.   <ftp://ftp.tunes.org/pub/tunes/obsolete/dist/tunes.0.0.0/tunes.0.0.0.25.src.zip>
  1251.   as examples of advanced macroprogramming using m4.
  1252.  
  1253.   However, its disfunctional quoting and unquoting semantics force you
  1254.   to use explicit continuation-passing tail-recursive macro style if you
  1255.   want to do advanced macro programming (which is remindful of TeX --
  1256.   BTW, has anyone tried to use TeX as a macroprocessor for anything else
  1257.   than typesetting ?).  This is NOT worse than CPP that does not allow
  1258.   quoting and recursion anyway.
  1259.  
  1260.   The right version of m4 to get is GNU m4 1.4 (or later if exists),
  1261.   which has the most features and the least bugs or limitations of all.
  1262.   m4 is designed to be slow for anything but the simplest uses, which
  1263.   might still be ok for most assembly programming (you're not writing
  1264.   million-lines assembly programs, are you?).
  1265.  
  1266.  
  1267.  
  1268.   4.2.3.  Macroprocessing with yer own filter
  1269.  
  1270.   You can write your own simple macro-expansion filter with the usual
  1271.   tools: perl, awk, sed, etc.  That's quick to do, and you control
  1272.   everything.  But of course, any power in macroprocessing must be
  1273.   earned the hard way.
  1274.  
  1275.  
  1276.  
  1277.   4.2.4.  Metaprogramming
  1278.  
  1279.   Instead of using an external filter that expands macros, one way to do
  1280.   things is to write programs that write part or all of other programs.
  1281.  
  1282.   For instance, you could use a program outputing source code
  1283.  
  1284.   ╖  to generate sine/cosine/whatever lookup tables,
  1285.  
  1286.   ╖  to extract a source-form representation of a binary file,
  1287.  
  1288.   ╖  to compile your bitmaps into fast display routines,
  1289.  
  1290.   ╖  to extract documentation, initialization/finalization code,
  1291.      description tables, as well as normal code from the same source
  1292.      files,
  1293.  
  1294.   ╖  to have customized assembly code, generated from a
  1295.      perl/shell/scheme script that does arbitrary processing,
  1296.  
  1297.   ╖  to propagate data defined at one point only into several cross-
  1298.      referencing tables and code chunks.
  1299.  
  1300.   ╖  etc.
  1301.  
  1302.   Think about it!
  1303.  
  1304.  
  1305.  
  1306.   4.2.4.1.  Backends from compilers
  1307.  
  1308.   Compilers like GCC, SML/NJ, Objective CAML, MIT-Scheme, CMUCL, etc, do
  1309.   have their own generic assembler backend, which you might choose to
  1310.   use, if you intend to generate code semi-automatically from the
  1311.   according languages, or from a language you hack: rather than write
  1312.   great assembly code, you may instead modify a compiler so that it
  1313.   dumps great assembly code!
  1314.  
  1315.  
  1316.  
  1317.   4.2.4.2.  The New-Jersey Machine-Code Toolkit
  1318.  
  1319.   There is a project, using the programming language Icon (with an
  1320.   experimental ML version), to build a basis for producing assembly-
  1321.   manipulating code.  See around
  1322.   <http://www.cs.virginia.edu/~nr/toolkit/>
  1323.  
  1324.  
  1325.  
  1326.   4.2.4.3.  TUNES
  1327.  
  1328.  
  1329.   The TUNES Project <http://www.tunes.org/> for a Free Reflective
  1330.   Computing System is developping its own assembler as an extension to
  1331.   the Scheme language, as part of its development process.  It doesn't
  1332.   run at all yet, though help is welcome.
  1333.  
  1334.   The assembler manipulates abstract syntax trees, so it could equally
  1335.   serve as the basis for a assembly syntax translator, a disassembler, a
  1336.   common assembler/compiler back-end, etc.  Also, the full power of a
  1337.   real language, Scheme, make it unchallenged as for
  1338.   macroprocessing/metaprograming.
  1339.  
  1340.  
  1341.  
  1342.  
  1343.  
  1344.   5.  CALLING CONVENTIONS
  1345.  
  1346.  
  1347.  
  1348.  
  1349.   5.1.  Linux
  1350.  
  1351.  
  1352.  
  1353.   5.1.1.  Linking to GCC
  1354.  
  1355.   That's the preferred way.  Check GCC docs and examples from Linux
  1356.   kernel .S files that go through gas (not those that go through as86).
  1357.  
  1358.   32-bit arguments are pushed down stack in reverse syntactic order
  1359.   (hence accessed/popped in the right order), above the 32-bit near
  1360.   return address.  %ebp, %esi, %edi, %ebx are callee-saved, other
  1361.   registers are caller-saved; %eax is to hold the result, or %edx:%eax
  1362.   for 64-bit results.
  1363.  
  1364.   FP stack: I'm not sure, but I think it's result in st(0), whole stack
  1365.   caller-saved.
  1366.  
  1367.   Note that GCC has options to modify the calling conventions by
  1368.   reserving registers, having arguments in registers, not assuming the
  1369.   FPU, etc. Check the i386 .info pages.
  1370.  
  1371.   Beware that you must then declare the cdecl or regparm(0) attribute
  1372.   for a function that will follow standard GCC calling conventions.  See
  1373.   in the GCC info pages the section: C Extensions::Extended Asm::.  See
  1374.   also how Linux defines its asmlinkage macro...
  1375.  
  1376.  
  1377.  
  1378.  
  1379.   5.1.2.  ELF vs a.out problems
  1380.  
  1381.   Some C compilers prepend an underscore before every symbol, while
  1382.   others do not.
  1383.  
  1384.   Particularly, Linux a.out GCC does such prepending, while Linux ELF
  1385.   GCC does not.
  1386.  
  1387.   If you need cope with both behaviors at once, see how existing
  1388.   packages do.  For instance, get an old Linux source tree, the Elk,
  1389.   qthreads, or OCAML...
  1390.  
  1391.   You can also override the implicit C->asm renaming by inserting
  1392.   statements like
  1393.  
  1394.   ______________________________________________________________________
  1395.           void foo asm("bar") (void);
  1396.   ______________________________________________________________________
  1397.  
  1398.  
  1399.   to be sure that the C function foo will be called really bar in assem¡
  1400.   bly.
  1401.  
  1402.   Note that the utility objcopy, from the binutils package, should allow
  1403.   you to transform your a.out objects into ELF objects, and perhaps the
  1404.   contrary too, in some cases.  More generally, it will do lots of file
  1405.   format conversions.
  1406.  
  1407.  
  1408.  
  1409.  
  1410.   5.1.3.  Direct Linux syscalls
  1411.  
  1412.   This is specifically NOT recommended, because the conventions change
  1413.   from time to time or from kernel flavor to kernel flavor (cf L4Linux),
  1414.   plus it's not portable, it's a burden to write, it's redundant with
  1415.   the libc effort, AND it precludes fixes and extensions that are made
  1416.   to the libc, like, for instance the zlibc package, that does on-the-
  1417.   fly transparent decompression of gzip-compressed files.  The standard,
  1418.   recommended way to call Linux system services is, and will stay, to go
  1419.   through the libc.
  1420.  
  1421.   Shared objects should keep your stuff small.  And if you really want
  1422.   smaller binaries, do use #! stuff, with the interpreter having all the
  1423.   overhead you want to keep out of your binaries.
  1424.  
  1425.   Now, if for some reason, you don't want to link to the libc, go get
  1426.   the libc and understand how it works!  After all, you're pretending to
  1427.   replace it, ain't you?  You might also take a look at how my eforth
  1428.   1.0c <ftp://ftp.forth.org/pub/Forth/Compilers/native/unix/Linux/linux-
  1429.   eforth-1.0c.tar.gz> does it.
  1430.  
  1431.   The sources for Linux come in handy, too, particularly the
  1432.   asm/unistd.h header file, that describes how to do system calls...
  1433.  
  1434.   Basically, you issue an int $0x80, with the __NR_syscallname number
  1435.   (from asm/unistd.h) in %eax, and parameters (up to five) in %ebx,
  1436.   %ecx, %edx, %esi, %edi respectively.  Result is returned in %eax, with
  1437.   a negative result being an error whose opposite is what libc would put
  1438.   in errno.  The user-stack is not touched, so you needn't have a valid
  1439.   one when doing a syscall.
  1440.  
  1441.  
  1442.  
  1443.   5.1.4.  I/O under Linux
  1444.  
  1445.   If you want to do direct I/O under Linux, either it's something very
  1446.   simple that needn't OS arbitration, and you should see the IO-Port-
  1447.   Programming mini-HOWTO; or it needs a kernel device driver, and you
  1448.   should try to learn more about kernel hacking, device driver
  1449.   development, kernel modules, etc, for which there are other excellent
  1450.   HOWTOs and documents from the LDP.
  1451.  
  1452.  
  1453.   Particularly, if what you want is Graphics programming, then do join
  1454.   the GGI project: <http://www.ggi-project.org/>
  1455.  
  1456.   Anyway, in all these cases, you'll be better off using GCC inline
  1457.   assembly with the macros from linux/asm/*.h than writing full assembly
  1458.   source files.
  1459.  
  1460.  
  1461.  
  1462.   5.1.5.  Accessing 16-bit drivers from Linux/i386
  1463.  
  1464.   Such thing is theoretically possible (proof: see how DOSEMU
  1465.   <http://www.dosemu.org> can selectively grant hardware port access to
  1466.   programs), and I've heard rumors that someone somewhere did actually
  1467.   do it (in the PCI driver? Some VESA access stuff? ISA PnP? dunno).  If
  1468.   you have some more precise information on that, you'll be most
  1469.   welcome.  Anyway, good places to look for more information are the
  1470.   Linux kernel sources, DOSEMU sources (and other programs in the DOSEMU
  1471.   repository <ftp://tsx-11.mit.edu/pub/linux/ALPHA/dosemu/>), and
  1472.   sources for various low-level programs under Linux...  (perhaps GGI if
  1473.   it supports VESA).
  1474.  
  1475.   Basically, you must either use 16-bit protected mode or vm86 mode.
  1476.  
  1477.   The first is simpler to setup, but only works with well-behaved code
  1478.   that won't do any kind of segment arithmetics or absolute segment
  1479.   addressing (particularly addressing segment 0), unless by chance it
  1480.   happens that all segments used can be setup in advance in the LDT.
  1481.  
  1482.   The later allows for more "compatibility" with vanilla 16-bit
  1483.   environments, but requires more complicated handling.
  1484.  
  1485.   In both cases, before you can jump to 16-bit code, you must
  1486.  
  1487.   ╖  mmap any absolute address used in the 16-bit code (such as ROM,
  1488.      video buffers, DMA targets, and memory-mapped I/O) from /dev/mem to
  1489.      your process' address space,
  1490.  
  1491.   ╖  setup the LDT and/or vm86 mode monitor.
  1492.  
  1493.   ╖  grab proper I/O permissions from the kernel (see the above section)
  1494.  
  1495.   Again, carefully read the source for the stuff contributed to the
  1496.   DOSEMU project, particularly these mini-emulators for running ELKS
  1497.   and/or simple .COM programs under Linux/i386.
  1498.  
  1499.  
  1500.  
  1501.   5.2.  DOS
  1502.  
  1503.   Most DOS extenders come with some interface to DOS services.  Read
  1504.   their docs about that, but often, they just simulate int $0x21 and
  1505.   such, so you do ``as if'' you were in real mode (I doubt they have
  1506.   more than stubs and extend things to work with 32-bit operands; they
  1507.   most likely will just reflect the interrupt into the real-mode or vm86
  1508.   handler).
  1509.  
  1510.   Docs about DPMI and such (and much more) can be found on
  1511.   <ftp://x2ftp.oulu.fi/pub/msdos/programming/> (again, the original
  1512.   x2ftp site is closing, so use a mirror site
  1513.   <ftp://ftp.lip6.fr/pub/pc/x2ftp/README.mirror_sites>).
  1514.  
  1515.   DJGPP comes with its own (limited) glibc
  1516.   derivative/subset/replacement, too.
  1517.  
  1518.  
  1519.   It is possible to cross-compile from Linux to DOS, see the
  1520.   devel/msdos/ directory of your local FTP mirror for metalab.unc.edu
  1521.   Also see the MOSS dos-extender from the Flux project
  1522.   <http://www.cs.utah.edu/projects/flux/> from university of Utah.
  1523.  
  1524.   Other documents and FAQs are more DOS-centered.  We do not recommend
  1525.   DOS development.
  1526.  
  1527.  
  1528.  
  1529.   5.3.  Winblows and suches
  1530.  
  1531.   Hey, this document covers only free software.  Ring me when Winblows
  1532.   becomes free, or when there are free dev tools for it!
  1533.  
  1534.   Well, after all there are: Cygnus Solutions <http://www.cygnus.com>
  1535.   has developped the cygwin32.dll library, for GNU programs to run on
  1536.   MacroShit platforms.  Thus, you can use GCC, GAS, all the GNU tools,
  1537.   and many other Unix applications.  Have a look around their homepage.
  1538.   I (FarΘ) don't intend to expand on Losedoze programming, but I'm sure
  1539.   you can find lots of documents about it everywhere...
  1540.  
  1541.  
  1542.  
  1543.   5.4.  Yer very own OS
  1544.  
  1545.   Control being what attract many programmers to assembly, want of OS
  1546.   development is often what leads to or stems from assembly hacking.
  1547.   Note that any system that allows self-development could be qualified
  1548.   an "OS" even though it might run "on top" of an underlying system that
  1549.   multitasking or I/O (much like Linux over Mach or OpenGenera over
  1550.   Unix), etc.  Hence, for easier debugging purpose, you might like to
  1551.   develop your ``OS'' first as a process running on top of Linux
  1552.   (despite the slowness), then use the Flux OS kit
  1553.   <http://www.cs.utah.edu/projects/flux/oskit/> (which grants use of
  1554.   Linux and BSD drivers in yer own OS) to make it standalone.  When your
  1555.   OS is stable, it's still time to write your own hardware drivers if
  1556.   you really love that.
  1557.  
  1558.   This HOWTO will not itself cover topics such as Boot loader code &
  1559.   getting into 32-bit mode, Handling Interrupts, The basics about intel
  1560.   ``protected mode'' or ``V86/R86'' braindeadness, defining your object
  1561.   format and calling conventions.  The main place where to find reliable
  1562.   information about that all is source code of existing OSes and
  1563.   bootloaders.  Lots of pointers lie in the following WWW page:
  1564.   <http://www.tunes.org/Review/OSes.html>
  1565.  
  1566.  
  1567.  
  1568.   6.  TODO & POINTERS
  1569.  
  1570.  
  1571.  
  1572.   ╖  find someone who has got some time to takeover the maintenance
  1573.  
  1574.   ╖  fill incomplete sections
  1575.  
  1576.   ╖  add more pointers to software and docs
  1577.  
  1578.   ╖  add simple examples from real life to illustrate the syntax, power,
  1579.      and limitations of each proposed solution.
  1580.  
  1581.   ╖  ask people to help with this HOWTO
  1582.  
  1583.   ╖  perhaps give a few words for assembly on other architectures than
  1584.      i386?
  1585.   ╖  A few pointers (in addition to those already in the rest of the
  1586.      HOWTO)
  1587.  
  1588.   ╖  80x86 CPU family references: intel manuals
  1589.      <http://www.intel.com/design/pentium/manuals/>; bugs
  1590.      <http://www.xs4all.nl/~feldmann/86bugs.htm>.
  1591.  
  1592.   ╖  ftp.luth.se <ftp://ftp.luth.se/pub/msdos/> mirrors the hornet and
  1593.      x2ftp former archives of msdos assembly coding stuff.
  1594.  
  1595.   ╖  A few starting points on the web about assembly programming: Jannes
  1596.      Faber's <http://www.fys.ruu.nl/~faber/Amain.html>; QZX's
  1597.      <http://www.qzx.com/library/>; JanW's <http://bewoner.dma.be/JanW>;
  1598.      this one (?) <ftp://zfja-gate.fuw.edu.pl/user/net/ka9q/guest/>
  1599.  
  1600.   ╖  Fun stuff: CoreWars <http://www.koth.org>, a fun way to learn
  1601.      assembly in general.
  1602.  
  1603.   ╖  USENET: comp.lang.asm.x86 <news://comp.lang.asm.x86>;
  1604.      alt.os.assembly <news://alt.os.assembly>.
  1605.  
  1606.   ╖  And of course, do use your usual Internet Search Tools to look for
  1607.      more information, and tell me anything interesting you find!
  1608.  
  1609.  
  1610.   Author's .sig:
  1611.  
  1612.   ## FarΘ | VN: ╨úng-V√ BΓn   | Join the TUNES project!  http://www.tunes.org/ ##
  1613.   ## FR: Franτois-RenΘ Rideau |    TUNES is a Useful, Not Expedient System     ##
  1614.   ## Reflection&Cybernethics  | Project for a Free Reflective Computing System ##
  1615.  
  1616.  
  1617.  
  1618.  
  1619.  
  1620.  
  1621.  
  1622.  
  1623.  
  1624.  
  1625.  
  1626.  
  1627.  
  1628.  
  1629.  
  1630.  
  1631.  
  1632.  
  1633.  
  1634.  
  1635.  
  1636.  
  1637.  
  1638.  
  1639.  
  1640.  
  1641.  
  1642.  
  1643.  
  1644.  
  1645.  
  1646.  
  1647.  
  1648.  
  1649.  
  1650.  
  1651.