<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-8901974503278002812</id><updated>2011-09-06T01:01:02.076-07:00</updated><category term='introduction'/><category term='records'/><category term='counting'/><category term='programming'/><category term='programming from the ground up'/><category term='robust programs'/><category term='files'/><category term='table of ascii'/><category term='x86'/><category term='high-level languages'/><category term='personal dedication'/><category term='important system calls'/><category term='functions'/><category term='memory'/><category term='using GDB debugger'/><category term='gui programming'/><category term='your first programs'/><category term='code libraries'/><category term='assembly language idioms'/><category term='asm'/><category term='GNU free documentation license'/><category term='computer architecture'/><category term='common x86 instructions'/><category term='document history'/><category term='optimization'/><category term='moving on'/><category term='assembly language'/><title type='text'>Programming from the Ground Up</title><subtitle type='html'>An introduction to programming using linux assembly language</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://programminggroundup.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8901974503278002812/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://programminggroundup.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Admin</name><uri>http://www.blogger.com/profile/13783659974416042562</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>23</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-8901974503278002812.post-8873629558860660077</id><published>2099-01-30T22:48:00.000-08:00</published><updated>2007-01-31T23:25:40.101-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='introduction'/><category scheme='http://www.blogger.com/atom/ns#' term='x86'/><category scheme='http://www.blogger.com/atom/ns#' term='asm'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='assembly language'/><title type='text'>Chapter 1: Introduction</title><content type='html'>&lt;div class="section"&gt; &lt;h2 class="sect2-title"&gt;&lt;a name="13"&gt;&lt;/a&gt;&lt;a name="ch01lev1sec1"&gt;&lt;/a&gt;Welcome to  Programming&lt;/h2&gt; &lt;p class="first-para"&gt;I love programming. I enjoy the challenge to not only make a  working program, but to do so with style. Programming is like poetry. It conveys  a message, not only to the computer, but to those who modify and use your  program. With a program, you build your own world with your own rules. You  create your world according to your conception of both the problem and the  solution. Masterful programmers create worlds with programs that are clear and  succinct, much like a poem or essay.&lt;/p&gt; &lt;p class="para"&gt;One of the greatest programmers, Donald Knuth, describes  programming not as telling a computer how to do something, but telling a person  how they would instruct a computer to do something. The point is that programs  are meant to be read by people, not just computers. Your programs will be  modified and updated by others long after you move on to other projects. Thus,  programming is not as much about communicating to a computer as it is  communicating to those who come after you. A programmer is a problem-solver, a  poet, and an instructor all at once. Your goal is to solve the problem at hand,  doing so with balance and taste, and teach your solution to future programmers.  I hope that this book can teach at least some of the poetry and magic that makes  computing exciting.&lt;/p&gt; &lt;p class="para"&gt;Most introductory books on programming frustrate me to no end. At  the end of them you can still ask "how does the computer really work?" and not  have a good answer. They tend to pass over topics that are difficult even though  they are important. I will take you through the difficult issues because that is  the only way to move on to masterful programming. My goal is to take you from  knowing nothing about programming to understanding how to think, write, and  learn like a programmer. You won't know everything, but you will have a  background for how everything fits together. At the end of this book, you should  be able to do the following:&lt;/p&gt;&lt;a name="14"&gt;&lt;/a&gt;&lt;a name="IDX-2"&gt;&lt;/a&gt; &lt;ul class="itemizedlist"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;Understand how a program works and interacts with other  programs&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;Read other people's programs and learn how they work&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;Learn new programming languages quickly&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;Learn advanced concepts in computer science  quickly&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p class="para"&gt;I will not teach you everything. Computer science is a massive  field, especially when you combine the theory with the practice of computer  programming. However, I will attempt to get you started on the foundations so  you can easily go wherever you want afterwards.&lt;/p&gt; &lt;p class="para"&gt;There is somewhat of a chicken and egg problem in teaching  programming, especially assembly language. There is a lot to learn - it is  almost too much to learn almost at all at once. However, each piece depends on  all the others, which makes learning it a piece at a time difficult. Therefore,  you must be patient with yourself and the computer while learning to program. If  you don't understand something the first time, reread it. If you still don't  understand it, it is sometimes best to take it by faith and come back to it  later. Often after more exposure to programming the ideas will make more sense.  Don't get discouraged. It's a long climb, but very worthwhile.&lt;/p&gt; &lt;p class="para"&gt;At the end of each chapter are three sets of review exercises. The  first set is more or less regurgitation - they check to see if can you give back  what you learned in the chapter. The second set contains application questions -  they check to see if you can apply what you learned to solve problems. The final  set is to see if you are capable of broadening your horizons. Some of these  questions may not be answerable until later in the book, but they give you some  things to think about. Other questions require some research into outside  sources to discover the answer. Still others require you to simply analyze your  options and explain a best solution. Many of the questions don't have right or  wrong answers, but that doesn't mean they are unimportant. Learning the issues  involved in programming, learning how to research answers, and learning how to  look ahead are all a major part of a programmer's work.&lt;/p&gt;&lt;a name="15"&gt;&lt;/a&gt;&lt;a name="IDX-3"&gt;&lt;/a&gt; &lt;p class="para"&gt;If you have problems that you just can't get past, there is a  mailing list for this book where readers can discuss and get help with what they  are reading. The address is &lt;&lt;a href="mailto:pgubook-readers@nongnu.org"&gt;&lt;span class="fixed"&gt;pgubook-readers@nongnu.org&lt;/span&gt;&lt;/a&gt;&gt;. This mailing list is open  for any type of question or discussion along the lines of this book. You can  subscribe to this list by going to &lt;a class="url" href="http://mail.nongnu.org/mailman/listinfo/pgubook-readers" target="_top"&gt;http://mail.nongnu.org/mailman/listinfo/pgubook-readers&lt;/a&gt;.&lt;/p&gt; &lt;p class="last-para"&gt;If you are thinking of using this book for a class on  computer programming but do not have access to Linux computers for your  students, I highly suggest you try to find help from the K-12 Linux Project.  Their website is at &lt;a class="url" href="http://www.k12linux.org/" target="_top"&gt;http://www.k12linux.org/&lt;/a&gt; and they have a helpful and responsive  mailing list available.&lt;/p&gt;&lt;div class="chapter"&gt;&lt;a name="ch01"&gt;&lt;/a&gt; &lt;div class="section"&gt; &lt;h2 class="first-section-title"&gt;&lt;a name="16"&gt;&lt;/a&gt;&lt;a name="ch01lev1sec2"&gt;&lt;/a&gt;Your  Tools&lt;/h2&gt; &lt;p class="first-para"&gt;This book teaches assembly language for x86 processors and  the GNU/Linux operating system. Therefore we will be giving all of the examples  using the GNU/Linux standard GCC tool set. If you are not familiar with  GNU/Linux and the GCC tool set, they will be described shortly. If you are new  to Linux, you should check out the guide available at &lt;a class="url" href="http://rute.sourceforge.net/" target="_top"&gt;http://rute.sourceforge.net/&lt;/a&gt;  &lt;sup&gt;[&lt;a href="http://www2.blogger.com/post-edit.g?blogID=8901974503278002812&amp;postID=8873629558860660077#ftn.N19" name="N19"&gt;1&lt;/a&gt;]&lt;/sup&gt; What I intend to show you is more  about programming in general than using a specific tool set on a specific  platform, but standardizing on one makes the task much easier.&lt;/p&gt; &lt;p class="para"&gt;Those new to Linux should also try to get involved in their local  GNU/Linux User's Group. User's Group members are usually very helpful for new  people, and will help you from everything from installing Linux to learning to  use it most efficiently. A listing of GNU/Linux User's Groups is available at &lt;a class="url" href="http://www.linux.org/groups/" target="_top"&gt;http://www.linux.org/groups/&lt;/a&gt; &lt;/p&gt; &lt;p class="para"&gt;All of these programs have been tested using Red Hat Linux 8.0,  and should work with any other GNU/Linux distribution, too. &lt;sup&gt;[&lt;a href="http://www2.blogger.com/post-edit.g?blogID=8901974503278002812&amp;amp;postID=8873629558860660077#ftn.N44" name="N44"&gt;2&lt;/a&gt;]&lt;/sup&gt; They will not work with non-Linux &lt;a name="17"&gt;&lt;/a&gt;&lt;a name="IDX-4"&gt;&lt;/a&gt;operating systems such as BSD or other systems.  However, all of the &lt;i class="emphasis"&gt;skills&lt;/i&gt; learned in this book should be  easily transferable to any other system.&lt;/p&gt; &lt;p class="para"&gt;If you do not have access to a GNU/Linux machine, you can look for  a hosting provider who offers a Linux &lt;i class="emphasis"&gt;shell account,&lt;/i&gt; which  is a command-line only interface to a Linux machine. There are many low-cost  shell account providers, but you have to make sure that they match the  requirements above (i.e. - Linux on x86). Someone at your local GNU/Linux User's  Group may be able to give you one as well. Shell accounts only require that you  already have an Internet connection and a telnet program. If you use Windows®,  you already have a telnet client - just click on &lt;span class="fixed"&gt;start&lt;/span&gt;,  then &lt;span class="fixed"&gt;run&lt;/span&gt;, then type in &lt;span class="fixed"&gt;telnet&lt;/span&gt;.  However, it is usually better to download PuTTY from &lt;a class="url" href="http://www.chiart.greenend.co.uk/%7Esgtatham/putty/" target="_top"&gt;http://www.chiart.greenend.co.uk/~sgtatham/putty/&lt;/a&gt; because  Windows' telnet has some weird problems. There are a lot of options for the  Macintosh, too. NiftyTelnet is my favorite.&lt;/p&gt; &lt;p class="para"&gt;If you don't have GNU/Linux and can't find a shell account  service, then you can download Knoppix from &lt;a class="url" href="http://www.knoppix.org/" target="_top"&gt;http://www.knoppix.org/&lt;/a&gt; Knoppix  is a GNU/Linux distribution that boots from CD so that you don't have to  actually install it. Once you are done using it, you just reboot and remove the  CD and you are back to your regular operating system.&lt;/p&gt; &lt;p class="para"&gt;So what is GNU/Linux? GNU/Linux is an operating system modeled  after UNIX®. The GNU part comes from the GNU Project (&lt;a class="url" href="http://www.gnu.org/" target="_top"&gt;http://www.gnu.org/&lt;/a&gt;) &lt;sup&gt;[&lt;a href="http://www2.blogger.com/post-edit.g?blogID=8901974503278002812&amp;postID=8873629558860660077#ftn.N91" name="N91"&gt;3&lt;/a&gt;]&lt;/sup&gt;, which includes most of the programs you  will run, including the GCC tool set that we will use to program with. The GCC  tool set contains all of the programs necessary to create programs in various  computer languages.&lt;/p&gt; &lt;p class="para"&gt;Linux is the name of the &lt;i class="emphasis"&gt;kernel.&lt;/i&gt; The kernel  is the core part of an operating system that keeps track of everything. The  kernel is both a fence and a gate. As a gate, it allows programs to access  hardware in a uniform way. Without the kernel, you would have to write programs  to deal with every device model ever made. The &lt;a name="18"&gt;&lt;/a&gt;&lt;a name="IDX-5"&gt;&lt;/a&gt;kernel handles all device-specific interactions so you don't have  to. It also handles file access and interaction between processes. For example,  when you type, your typing goes through several programs before it hits your  editor. First, the kernel is what handles your hardware, so it is the first to  receive notice about the keypress. The keyboard sends in &lt;i class="emphasis"&gt;scancodes&lt;/i&gt; to the kernel, which then converts them to the  actual letters, numbers, and symbols they represent. If you are using a  windowing system (like Microsoft Windows® or the X Window System), then the  windowing system reads the keypress from the kernel, and delivers it to whatever  program is currently in focus on the user's display.&lt;/p&gt; &lt;div class="example"&gt;&lt;span class="example-title"&gt;&lt;span class="example-titlelabel"&gt;Example 1-1: &lt;/span&gt;How the computer processes keyboard  sigals&lt;/span&gt;&lt;a name="19"&gt;&lt;/a&gt;&lt;a name="ch01ex01"&gt;&lt;/a&gt;  &lt;div class="formalbody"&gt; &lt;table class="BlueLine" border="0" cellpadding="0" cellspacing="0" width="100%"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td class="bluecell" bg="" style="color: rgb(0, 0, 128);"&gt;&lt;span style="color: rgb(1, 1, 0);font-family:Arial;font-size:85%;"  &gt;&lt;b&gt;&lt;img alt="Start example" src="http://www2.blogger.com/_.gif" border="0" height="2" width="1" /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;Keyboard -&gt; Kernel -&gt; Windowing system -&gt; Application program&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;table class="BlueLine" border="0" cellpadding="0" cellspacing="0" width="100%"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td class="bluecell" bg="" style="color: rgb(0, 0, 128);"&gt;&lt;span style="color: rgb(1, 1, 0);font-family:Arial;font-size:85%;"  &gt;&lt;b&gt;&lt;img alt="End example" src="http://www2.blogger.com/_.gif" border="0" height="2" width="1" /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt; &lt;table class="BlankSpace" border="0" cellpadding="0" cellspacing="0" width="100%"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td height="16"&gt;&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;/div&gt; &lt;p class="para"&gt;The kernel also controls the flow of information between programs.  The kernel is a program's gate to the world around it. Every time that data  moves between processes, the kernel controls the messaging. In our keyboard  example above, the kernel would have to be involved for the windowing system to  communicate the keypress to the application program.&lt;/p&gt; &lt;p class="para"&gt;As a fence, the kernel prevents programs from accidentally  overwriting each other's data and from accessing files and devices that they  don't have permission to. It limits the amount of damage a poorly-written  program can do to other running programs.&lt;/p&gt; &lt;p class="para"&gt;In our case, the kernel is Linux. Now, the kernel all by itself  won't do anything. You can't even boot up a computer with just a kernel. Think  of the kernel as the water pipes for a house. Without the pipes, the faucets  won't work, but the pipes are pretty useless if there are no faucets. Together,  the user applications (from the GNU project and other places) and the kernel  (Linux) make up the entire operating system, GNU/Linux.&lt;/p&gt; &lt;p class="para"&gt;For the most part, this book will be using the computer's  low-level assembly language. There are essentially three kinds of  languages:&lt;/p&gt;&lt;a name="20"&gt;&lt;/a&gt;&lt;a name="IDX-6"&gt;&lt;/a&gt; &lt;p class="para"&gt;Machine Language&lt;/p&gt; &lt;ul class="simple-list"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;This is what the computer actually sees and deals with.  Every command the computer sees is given as a number or sequence of  numbers.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p class="para"&gt;Assembly Language&lt;/p&gt; &lt;ul class="simple-list"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;This is the same as machine language, except the command  numbers have been replaced by letter sequences which are easier to memorize.  Other small things are done to make it easier as well.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p class="para"&gt;High-Level Language&lt;/p&gt; &lt;ul class="simple-list"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;High-level languages are there to make programming easier.  Assembly language requires you to work with the machine itself. High-level  languages allow you to describe the program in a more natural language. A single  command in a high-level language usually is equivalent to several commands in an  assembly language.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p class="last-para"&gt;In this book we will learn assembly language, although we  will cover a bit of high-level languages. Hopefully by learning assembly  language, your understanding of how programming and computers work will put you  a step ahead.&lt;/p&gt;&lt;/div&gt; &lt;div class="footnotes"&gt; &lt;div class="footnote"&gt; &lt;p&gt;&lt;sup&gt;[&lt;a href="http://www2.blogger.com/post-edit.g?blogID=8901974503278002812&amp;postID=8873629558860660077#N19" name="ftn.N19"&gt;1&lt;/a&gt;]&lt;/sup&gt;This is quite a large document.  You certainly don't need to know everything to get started with this book. You  simply need to know how to navigate from the command line and how to use an  editor like &lt;span class="fixed"&gt;pico&lt;/span&gt;, &lt;span class="fixed"&gt;emacs&lt;/span&gt;, or  &lt;span class="fixed"&gt;vi&lt;/span&gt; (or others).&lt;/p&gt;&lt;/div&gt; &lt;div class="footnote"&gt; &lt;p&gt;&lt;sup&gt;[&lt;a href="http://www2.blogger.com/post-edit.g?blogID=8901974503278002812&amp;amp;postID=8873629558860660077#N44" name="ftn.N44"&gt;2&lt;/a&gt;]&lt;/sup&gt;By "GNU/Linux distribution", I  mean an x86 GNU/Linux distribution. GNU/Linux dis- tributions for the Power  Macintosh, the Alpha processor, or other processors will not work with this  book.&lt;/p&gt;&lt;/div&gt; &lt;div class="footnote"&gt; &lt;p&gt;&lt;sup&gt;[&lt;a href="http://www2.blogger.com/post-edit.g?blogID=8901974503278002812&amp;amp;postID=8873629558860660077#N91" name="ftn.N91"&gt;3&lt;/a&gt;]&lt;/sup&gt;The GNU Project is a project by  the Free Software Foundation to produce a complete, free operating  system.&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8901974503278002812-8873629558860660077?l=programminggroundup.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://programminggroundup.blogspot.com/feeds/8873629558860660077/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8901974503278002812&amp;postID=8873629558860660077' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8901974503278002812/posts/default/8873629558860660077'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8901974503278002812/posts/default/8873629558860660077'/><link rel='alternate' type='text/html' href='http://programminggroundup.blogspot.com/2007/01/chapter-1-introduction.html' title='Chapter 1: Introduction'/><author><name>Admin</name><uri>http://www.blogger.com/profile/13783659974416042562</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8901974503278002812.post-1835000085211923964</id><published>2007-01-31T21:48:00.000-08:00</published><updated>2007-01-31T21:50:23.060-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='x86'/><category scheme='http://www.blogger.com/atom/ns#' term='asm'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='assembly language'/><category scheme='http://www.blogger.com/atom/ns#' term='programming from the ground up'/><title type='text'>Programming from the Ground Up</title><content type='html'>&lt;div class="authorgroup"&gt; &lt;div class="author"&gt;Jonathan Bartlett&lt;/div&gt; &lt;div class="author"&gt;Edited by Dominick Bruno, Jr.&lt;/div&gt;&lt;/div&gt; &lt;p class="copyright"&gt;Copyright © &lt;i class="emphasis"&gt;&lt;a name="4"&gt;&lt;/a&gt;&lt;a name="IDX-ii"&gt;&lt;/a&gt;&lt;/i&gt;2004 by Jonathan Bartlett&lt;/p&gt; &lt;div class="legalnotice"&gt; &lt;p class="first-para"&gt;Permission is granted to copy, distribute and/or modify this  document under the terms of the GNU Free Documentation License, Version 1.1 or  any later version published by the Free Software Foundation; with no Invariant  Sections, with no Front-Cover Texts, and with no Back-Cover Texts. A copy of the  license is included in &lt;span class="chapterjump"&gt;Appendix H&lt;/span&gt;. In addition, you are granted full rights to use  the code examples for any purpose without even having to credit the authors.&lt;/p&gt; &lt;p class="first-para"&gt;To receive a copy of this book in electronic form, please  visit the website &lt;a class="url" href="http://savannah.nongnu.org/projects/pgubook/" target="_top"&gt;http://savannah.nongnu.org/projects/pgubook/&lt;/a&gt; This site contains  the instructions for downloading a transparent copy of this book as defined by  the GNU Free Documentation License.&lt;/p&gt; &lt;p class="first-para"&gt;All trademarks are property of their respective  owners.&lt;/p&gt;&lt;/div&gt;&lt;span class="isbn"&gt;ISBN 0-9752838-4-7&lt;br /&gt;&lt;/span&gt; &lt;div class="legalnotice"&gt; &lt;p class="first-para"&gt;Published by Bartlett Publishing in Broken Arrow,  Oklahom&lt;/p&gt; &lt;p class="first-para"&gt;Library of Congress Control Number: 2004091465&lt;/p&gt; &lt;p class="first-para"&gt;Bartlett Publishing Cataloging-in-Publication Data&lt;/p&gt; &lt;p class="first-para"&gt; &lt;/p&gt;&lt;div class="informalexample"&gt;&lt;pre class="literallayout-normal"&gt;Bartlett, Jonathan, 1977-&lt;br /&gt;         Programming from the ground up / Jonathan Bartlett ; edited by Dominick&lt;br /&gt;      Bruno.&lt;br /&gt;           p.     cm.&lt;br /&gt;        Includes index.&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;  &lt;p class="first-para"&gt;ISBN 0-9752838-4-7&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="subjectset"&gt;&lt;span class="subject"&gt;&lt;span class="subjectterm"&gt;1.  Linux.&lt;/span&gt;&lt;/span&gt; &lt;span class="subject"&gt;&lt;span class="subjectterm"&gt;2. Operating  systems (Computers)&lt;/span&gt;&lt;/span&gt; &lt;span class="subject"&gt;&lt;span class="subjectterm"&gt;3.  Computer programming.&lt;/span&gt;&lt;/span&gt; &lt;span class="subject"&gt;&lt;span class="subjectterm"&gt;I. Bruno, Dominick.&lt;/span&gt;&lt;/span&gt; &lt;span class="subject"&gt;&lt;span class="subjectterm"&gt;II. Title.&lt;/span&gt;&lt;/span&gt; &lt;/div&gt; &lt;div class="legalnotice"&gt; &lt;p class="first-para"&gt;QA76.76.O63 2004&lt;/p&gt; &lt;p class="first-para"&gt;005.268—dc22 2004091465&lt;a name="5"&gt;&lt;/a&gt;&lt;a name="IDX-iii"&gt;&lt;/a&gt;  &lt;/p&gt; &lt;p class="first-para"&gt;This book can be purchased at &lt;a class="url" href="http://www.bartlettpublishing.com/" target="_top"&gt;http://www.bartlettpublishing.com/&lt;/a&gt; &lt;/p&gt; &lt;p class="first-para"&gt;This book is not a reference book, it is an introductory  book. It is therefore not suitable by itself to learn how to professionally  program in x86 assembly language, as some details have been left out to make the  learning process smoother. The point of the book is to help the student  understand how assembly language and computer programming works, not to be a  reference to the subject. Reference information about a particular processor can  be obtained by contacting the company which makes it.&lt;/p&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8901974503278002812-1835000085211923964?l=programminggroundup.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://programminggroundup.blogspot.com/feeds/1835000085211923964/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8901974503278002812&amp;postID=1835000085211923964' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8901974503278002812/posts/default/1835000085211923964'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8901974503278002812/posts/default/1835000085211923964'/><link rel='alternate' type='text/html' href='http://programminggroundup.blogspot.com/2007/01/programming-from-ground-up.html' title='Programming from the Ground Up'/><author><name>Admin</name><uri>http://www.blogger.com/profile/13783659974416042562</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8901974503278002812.post-2722055500275018457</id><published>2007-01-31T19:56:00.000-08:00</published><updated>2007-01-31T19:58:25.699-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='x86'/><category scheme='http://www.blogger.com/atom/ns#' term='asm'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='assembly language'/><category scheme='http://www.blogger.com/atom/ns#' term='personal dedication'/><title type='text'>Appendix I: Personal Dedication</title><content type='html'>&lt;p class="para"&gt;There are so many people I could thank. I will name here but a few  of the people who have brought me to where I am today. The many family members,  Sunday School teachers, youth pastors, school teachers, friends, and other  relationships that God has brought into my life to lead me, help me, and teach  me are too many to count. This book is dedicated to you all.&lt;/p&gt; &lt;p class="para"&gt;There are some people, however, that I would like to thank  specifically.&lt;/p&gt; &lt;p class="para"&gt;First of all, I want to thank the members of the Vineyard  Christian Fellowship Church in Champaign, Illinois for everything that you have  done to help me and my family in our times of crisis. It's been a long time  since I've seen or heard from any of you, but I think about you always. You have  been such a blessing to me, my wife, and Daniel, and I could never thank you  enough for showing us Christ's love when we needed it most. I thank God every  time I think of you - I thank Him for bringing you all to us in our deepest  times of need. Even out in the middle of Illinois with no friends of family, God  showed that He was still watching after us. Thank you for being His hands on  Earth. Specifically, I'd like to thank Joe and Rhonda, Pam and Dell, and  Herschel and Vicki. There were many, many others, too - so many people helped us  that it would be impossible to list them all.&lt;/p&gt; &lt;p class="para"&gt;I also want to thank my parents, who gave me the example of  perserverance and strength in hard times. Your example has helped me be a good  father to my children, and a good husband to my wife.&lt;/p&gt; &lt;p class="para"&gt;I also want to thank my wife, who even from when we first started  dating encouraged me to seek God in everything. Thank you for your support in  writing this book, and more importantly, for your support in being obedient to  God.&lt;/p&gt; &lt;p class="para"&gt;I also want to thanks the Little Light House school. My entire  family is continually blessed by the help you give to our son.&lt;/p&gt; &lt;p class="para"&gt;I also want to thank Joe and D.A. Thank you for taking a chance on  me in ministry. Being able to be a part of God's ministry again has helped me in  so many ways.&lt;/p&gt;&lt;a name="505"&gt;&lt;/a&gt;&lt;a name="IDX-312"&gt;&lt;/a&gt; &lt;p class="last-para"&gt;You all have given me the strength I needed to write this  book over the last few years. Without your support, I would have been too  overwhelmed by personal crises to even think about anything more than getting  through a day, much less putting this book together. You have all been a great  blessing to me, and I will keep you in my prayers always.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8901974503278002812-2722055500275018457?l=programminggroundup.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://programminggroundup.blogspot.com/feeds/2722055500275018457/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8901974503278002812&amp;postID=2722055500275018457' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8901974503278002812/posts/default/2722055500275018457'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8901974503278002812/posts/default/2722055500275018457'/><link rel='alternate' type='text/html' href='http://programminggroundup.blogspot.com/2007/01/appendix-i-personal-dedication.html' title='Appendix I: Personal Dedication'/><author><name>Admin</name><uri>http://www.blogger.com/profile/13783659974416042562</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8901974503278002812.post-3614831636123756537</id><published>2007-01-31T19:55:00.000-08:00</published><updated>2007-01-31T19:56:28.938-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='x86'/><category scheme='http://www.blogger.com/atom/ns#' term='asm'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='GNU free documentation license'/><category scheme='http://www.blogger.com/atom/ns#' term='assembly language'/><title type='text'>Appendix H: GNU Free Documentation License</title><content type='html'>&lt;p class="para"&gt;&lt;span class="fixed"&gt;0. PREAMBLE&lt;/span&gt; &lt;/p&gt; &lt;p class="para"&gt;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.&lt;/p&gt; &lt;p class="para"&gt;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.&lt;/p&gt; &lt;p class="para"&gt;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.&lt;/p&gt; &lt;p class="para"&gt;&lt;span class="fixed"&gt;1. APPLICABILITY AND DEFINITIONS&lt;/span&gt; &lt;/p&gt; &lt;p class="para"&gt;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".&lt;/p&gt; &lt;p class="para"&gt;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.&lt;/p&gt; &lt;p class="para"&gt;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 &lt;a name="494"&gt;&lt;/a&gt;&lt;a name="IDX-302"&gt;&lt;/a&gt;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.&lt;/p&gt; &lt;p class="para"&gt;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.&lt;/p&gt; &lt;p class="para"&gt;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.&lt;/p&gt; &lt;p class="para"&gt;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".&lt;/p&gt; &lt;p class="para"&gt;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.&lt;/p&gt; &lt;p class="para"&gt;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 &lt;a name="495"&gt;&lt;/a&gt;&lt;a name="IDX-303"&gt;&lt;/a&gt;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.&lt;/p&gt; &lt;p class="para"&gt;&lt;span class="fixed"&gt;2. VERBATIM COPYING&lt;/span&gt; &lt;/p&gt; &lt;p class="para"&gt;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.&lt;/p&gt; &lt;p class="para"&gt;You may also lend copies, under the same conditions stated above,  and you may publicly display copies.&lt;/p&gt; &lt;p class="para"&gt;&lt;span class="fixed"&gt;3. COPYING IN QUANTITY&lt;/span&gt; &lt;/p&gt; &lt;p class="para"&gt;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.&lt;/p&gt; &lt;p class="para"&gt;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.&lt;/p&gt; &lt;p class="para"&gt;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 &lt;a name="496"&gt;&lt;/a&gt;&lt;a name="IDX-304"&gt;&lt;/a&gt;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.&lt;/p&gt; &lt;p class="para"&gt;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.&lt;/p&gt; &lt;p class="para"&gt;&lt;span class="fixed"&gt;4. MODIFICATIONS&lt;/span&gt; &lt;/p&gt; &lt;p class="para"&gt;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:&lt;/p&gt; &lt;ul class="itemizedlist"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;&lt;b class="bold"&gt;A.&lt;/b&gt; 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.&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;&lt;b class="bold"&gt;B.&lt;/b&gt; 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).&lt;/p&gt;&lt;a name="497"&gt;&lt;/a&gt;&lt;a name="IDX-305"&gt;&lt;/a&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;&lt;b class="bold"&gt;C.&lt;/b&gt; State on the Title Page the name of the  publisher of the Modified Version, as the publisher.&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;&lt;b class="bold"&gt;D.&lt;/b&gt; Preserve all the copyright notices of  the Document.&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;&lt;b class="bold"&gt;E.&lt;/b&gt; Add an appropriate copyright notice for  your modifications adjacent to the other copyright notices.&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;&lt;b class="bold"&gt;F.&lt;/b&gt; 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.&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;&lt;b class="bold"&gt;G.&lt;/b&gt; Preserve in that license notice the  full lists of Invariant Sections and required Cover Texts given in the  Document's license notice.&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;&lt;b class="bold"&gt;H.&lt;/b&gt; Include an unaltered copy of this  License.&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;&lt;b class="bold"&gt;I.&lt;/b&gt; 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.&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;&lt;b class="bold"&gt;J.&lt;/b&gt; 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.&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;&lt;b class="bold"&gt;K.&lt;/b&gt; 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.&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;&lt;b class="bold"&gt;L.&lt;/b&gt; 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 &lt;a name="498"&gt;&lt;/a&gt;&lt;a name="IDX-306"&gt;&lt;/a&gt;the section titles.&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;&lt;b class="bold"&gt;M.&lt;/b&gt; Delete any section entitled  "Endorsements". Such a section may not be included in the Modified Version.&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;&lt;b class="bold"&gt;N.&lt;/b&gt; Do not retitle any existing section as  "Endorsements" or to conflict in title with any Invariant Section.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p class="para"&gt;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.&lt;/p&gt; &lt;p class="para"&gt;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.&lt;/p&gt; &lt;p class="para"&gt;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.&lt;/p&gt; &lt;p class="para"&gt;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.&lt;/p&gt; &lt;p class="para"&gt;&lt;span class="fixed"&gt;5. COMBINING DOCUMENTS&lt;/span&gt; &lt;/p&gt; &lt;p class="para"&gt;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 &lt;a name="499"&gt;&lt;/a&gt;&lt;a name="IDX-307"&gt;&lt;/a&gt;the original documents, unmodified,  and list them all as Invariant Sections of your combined work in its license  notice.&lt;/p&gt; &lt;p class="para"&gt;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.&lt;/p&gt; &lt;p class="para"&gt;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."&lt;/p&gt; &lt;p class="para"&gt;&lt;span class="fixed"&gt;6. COLLECTIONS OF DOCUMENTS&lt;/span&gt; &lt;/p&gt; &lt;p class="para"&gt;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.&lt;/p&gt; &lt;p class="para"&gt;You may extract a single document from such a collection, and  dispbibute 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.&lt;/p&gt; &lt;p class="para"&gt;&lt;span class="fixed"&gt;7. AGGREGATION WITH INDEPENDENT WORKS&lt;/span&gt;  &lt;/p&gt; &lt;p class="para"&gt;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 &lt;a name="500"&gt;&lt;/a&gt;&lt;a name="IDX-308"&gt;&lt;/a&gt;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. 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.&lt;/p&gt; &lt;p class="para"&gt;&lt;span class="fixed"&gt;8. TRANSLATION&lt;/span&gt; &lt;/p&gt; &lt;p class="para"&gt;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.&lt;/p&gt; &lt;p class="para"&gt;&lt;span class="fixed"&gt;9. TERMINATION&lt;/span&gt; &lt;/p&gt; &lt;p class="para"&gt;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.&lt;/p&gt; &lt;p class="para"&gt;&lt;span class="fixed"&gt;10. FUTURE REVISIONS OF THIS LICENSE&lt;/span&gt; &lt;/p&gt; &lt;p class="para"&gt;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 &lt;a class="url" href="http://www.gnu.org/copyleft/" target="_top"&gt;http://www.gnu.org/copyleft/&lt;/a&gt;.&lt;/p&gt; &lt;p class="para"&gt;Each version of the License is given a distinguishing version  number. If the &lt;a name="501"&gt;&lt;/a&gt;&lt;a name="IDX-309"&gt;&lt;/a&gt;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.&lt;/p&gt; &lt;p class="para"&gt;&lt;span class="fixed"&gt;Addendum&lt;/span&gt; &lt;/p&gt; &lt;p class="para"&gt;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:&lt;/p&gt; &lt;blockquote class="blockquote"&gt; &lt;p class="first-para"&gt;Copyright © YEAR YOUR NAME.&lt;/p&gt; &lt;p class="last-para"&gt;Permission is granted to copy, distribute and/or modify this  document under the terms of the GNU Free Documentation License, Version 1.1 or  any later version published by the Free Software Foundation; with the Invariant  Sections being LIST THEIR TITLES, with the Front-Cover Texts being LIST, and  with the Back-Cover Texts being LIST. A copy of the license is included in the  section entitled "GNU Free Documentation License".&lt;/p&gt;&lt;/blockquote&gt; &lt;p class="para"&gt;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.&lt;/p&gt; &lt;p class="para"&gt;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.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8901974503278002812-3614831636123756537?l=programminggroundup.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://programminggroundup.blogspot.com/feeds/3614831636123756537/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8901974503278002812&amp;postID=3614831636123756537' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8901974503278002812/posts/default/3614831636123756537'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8901974503278002812/posts/default/3614831636123756537'/><link rel='alternate' type='text/html' href='http://programminggroundup.blogspot.com/2007/01/appendix-h-gnu-free-documentation.html' title='Appendix H: GNU Free Documentation License'/><author><name>Admin</name><uri>http://www.blogger.com/profile/13783659974416042562</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8901974503278002812.post-8946538419889373665</id><published>2007-01-31T19:54:00.000-08:00</published><updated>2007-01-31T20:30:32.103-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='x86'/><category scheme='http://www.blogger.com/atom/ns#' term='asm'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='assembly language'/><category scheme='http://www.blogger.com/atom/ns#' term='document history'/><title type='text'>Appendix G: Document History</title><content type='html'>&lt;ul class="itemizedlist"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;12/17/2002 - Version 0.5 - Initial posting of book under GNU  FDL&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;07/18/2003 - Version 0.6 - Added ASCII appendix, finished  the discussion of the CPU in the Memory chapter, reworked exercises into a new  format, corrected several errors. Thanks to Harald Korneliussen for the many  suggestions and the ASCII table.&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;01/11/2004 - Version 0.7 - Added C translation appendix,  added the beginnings of an appendix of x86 instructions, added the beginnings of  a GDB appendix, finished out the files chapter, finished out the counting  chapter, added a records chapter, created a source file of common linux  definitions, corrected several errors, and lots of other fixes&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;01/22/2004 - Version 0.8 - Finished GDB appendix, mostly  finished w/appendix of x86 instructions, added section on planning programs,  added lots of review questions, and got everything to a completed, initial draft  state.&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;01/29/2004 - Version 0.9 - Lots of editting of all chapters.  Made code more consistent and made explanations clearer. Added some  illustrations.&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;01/31/2004 - Version 1.0 - Rewrote &lt;span class="chapterjump"&gt;chapter 9&lt;/span&gt;. Added full index. Lots of  minor corrections.&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;04/18/2004 - Version 1.1 - Lots of minor updates based on  reader comments. Made cleared distinction between dynamic and shared libraries.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8901974503278002812-8946538419889373665?l=programminggroundup.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://programminggroundup.blogspot.com/feeds/8946538419889373665/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8901974503278002812&amp;postID=8946538419889373665' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8901974503278002812/posts/default/8946538419889373665'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8901974503278002812/posts/default/8946538419889373665'/><link rel='alternate' type='text/html' href='http://programminggroundup.blogspot.com/2007/01/appendix-g-document-history.html' title='Appendix G: Document History'/><author><name>Admin</name><uri>http://www.blogger.com/profile/13783659974416042562</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8901974503278002812.post-3226452148093871097</id><published>2007-01-31T19:51:00.000-08:00</published><updated>2007-01-31T20:29:55.015-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='x86'/><category scheme='http://www.blogger.com/atom/ns#' term='asm'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='assembly language'/><category scheme='http://www.blogger.com/atom/ns#' term='using GDB debugger'/><title type='text'>Appendix F: Using the GDB Debugger</title><content type='html'>&lt;div class="section"&gt; &lt;h2 class="sect2-title"&gt;&lt;a name="474"&gt;&lt;/a&gt;Overview&lt;/h2&gt;&lt;a name="475"&gt;&lt;/a&gt;&lt;a name="IDX-289"&gt;&lt;/a&gt; &lt;div class="highlights"&gt; &lt;p class="first-para"&gt;By the time you read this appendix, you will likely have  written at least one program with an error in it. In assembly language, even  minor errors usually have results such as the whole program crashing with a  segmentation fault error. In most programming languages, you can simply print  out the values in your variables as you go along, and use that output to find  out where you went wrong. In assembly language, calling output functions is not  so easy. Therefore, to aid in determining the source of errors, you must use a  &lt;i class="emphasis"&gt;source debugger.&lt;/i&gt; &lt;/p&gt; &lt;p class="para"&gt;A debugger is a program that helps you find bugs by stepping  through the program one step at a time, letting you examine memory and register  contents along the way. A &lt;i class="emphasis"&gt;source debugger&lt;/i&gt; is a debugger  that allows you to tie the debugging operation directly to the source code of a  program. This means that the debugger allows you to look at the source code as  you typed it in - complete with symbols, labels, and comments.&lt;/p&gt; &lt;p class="last-para"&gt;The debugger we will be looking at is GDB - the GNU Debugger.  This application is present on almost all GNU/Linux distributions. It can debug  programs in multiple programming languages, including assembly  language.&lt;/p&gt;&lt;div class="section"&gt; &lt;h2 class="first-section-title"&gt;&lt;a name="476"&gt;&lt;/a&gt;&lt;a name="ap06lev1sec1"&gt;&lt;/a&gt;An  Example Debugging Session&lt;/h2&gt; &lt;p class="first-para"&gt;The best way to explain how a debugger works is by using it.  The program we will be using the debugger on is the &lt;span class="fixed"&gt;maximum&lt;/span&gt; program used in &lt;span class="chapterjump"&gt;Chapter 3&lt;/span&gt;. Let's say that you entered  the program perfectly, except that you left out the line:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt; incl %edi&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;When you run the program, it just goes in an infinite loop - it  never exits. To determine the cause, you need to run the program under GDB.  However, to do this, you need to have the assembler include debugging  information in the executable. All you need to do to enable this is to add the  &lt;span class="fixed"&gt;--gstabs&lt;/span&gt; option to the &lt;span class="fixed"&gt;as&lt;/span&gt;  command. So, you would assemble it like this:&lt;/p&gt;&lt;a name="477"&gt;&lt;/a&gt;&lt;a name="IDX-290"&gt;&lt;/a&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;as --gstabs maximum.s -o maximum.o&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;Linking would be the same as normal. "stabs" is the debugging  format used by GDB. Now, to run the program under the debugger, you would type  in &lt;span class="fixed"&gt;gdb ./maximum&lt;/span&gt;. Be sure that the source files are in  the current directory. The output should look similar to this:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;GNU gdb Red Hat Linux (5.2.1-4)&lt;br /&gt;Copyright 2002 Free Software Foundation, Inc.&lt;br /&gt;GDB is free software, covered by the GNU General Public&lt;br /&gt;License, and you are welcome to change it and/or&lt;br /&gt;distribute copies of it under certain conditions. Type&lt;br /&gt;"show copying" to see the conditions.  There is&lt;br /&gt;absolutely no warranty for GDB.  Type "show warranty"&lt;br /&gt;for details.&lt;br /&gt;This GDB was configured as "i386-redhat-linux"...&lt;br /&gt;(gdb)&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;Depending on which version of GDB you are running, this output may  vary slightly. At this point, the program is loaded, but is not running yet. The  debugger is waiting your command. To run your program, just type in &lt;span class="fixed"&gt;run&lt;/span&gt;. This will not return, because the program is running in  an infinite loop. To stop the program, hit control-c. The screen will then say  this:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;Starting program: /home/johnnyb/maximum&lt;br /&gt;&lt;br /&gt;Program received signal SIGINT, Interrupt.&lt;br /&gt;start_loop () at maximum.s:34&lt;br /&gt;34              movl data_items(,%edi,4), %eax&lt;br /&gt;Current language:  auto; currently asm&lt;br /&gt;(gdb)&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;This tells you that the program was interrupted by the SIGINT  signal (from your control-c), and was within the section labelled &lt;span class="fixed"&gt;start_loop&lt;/span&gt;, and was executing on line 34 when it stopped. It  gives you the code that it is about to execute.&lt;/p&gt;&lt;a name="478"&gt;&lt;/a&gt;&lt;a name="IDX-291"&gt;&lt;/a&gt; &lt;p class="para"&gt;Depending on exactly when you hit control-c, it may have stopped  on a different line or a different instruction than the example.&lt;/p&gt; &lt;p class="para"&gt;One of the best ways to find bugs in a program is to follow the  flow of the program to see where it is branching incorrectly. To follow the flow  of this program, keep on entering &lt;span class="fixed"&gt;stepi&lt;/span&gt; (for "step  instruction"), which will cause the computer to execute one instruction at a  time. If you do this several times, your output will look something like  this:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;(gdb) stepi&lt;br /&gt;35                  cmpl %ebx, %eax&lt;br /&gt;(gdb) stepi&lt;br /&gt;36                  jle start_loop&lt;br /&gt;(gdb) stepi&lt;br /&gt;32                  cmpl $0, %eax&lt;br /&gt;(gdb) stepi&lt;br /&gt;33                  je loop_exit&lt;br /&gt;(gdb) stepi&lt;br /&gt;34                  movl data_items(,%edi,4), %eax&lt;br /&gt;(gdb) stepi&lt;br /&gt;35                  cmpl %ebx, %eax&lt;br /&gt;(gdb) stepi&lt;br /&gt;36                  jle start_loop&lt;br /&gt;(gdb) step&lt;br /&gt;32                  cmpl $0, %eax&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;As you can tell, it has looped. In general, this is good, since we  wrote it to loop. However, the problem is that it is &lt;i class="emphasis"&gt;never  stopping.&lt;/i&gt; Therefore, to find out what the problem is, let's look at the  point in our code where we should be exitting the loop:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;cmpl  $0, %eax&lt;br /&gt;je    loop_exit&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;Basically, it is checking to see if &lt;span class="fixed"&gt;%eax&lt;/span&gt;  hits zero. If so, it should exit the loop. There are several things to check  here. First of all, you may have left this piece out &lt;a name="479"&gt;&lt;/a&gt;&lt;a name="IDX-292"&gt;&lt;/a&gt;altogether. It is not uncommon for a programmer to forget to  include a way to exit a loop. However, this is not the case here. Second, you  should make sure that &lt;span class="fixed"&gt;loop_exit&lt;/span&gt; actually is outside the  loop. If we put the label in the wrong place, strange things would happen.  However, again, this is not the case.&lt;/p&gt; &lt;p class="para"&gt;Neither of those potential problems are the culprit. So, the next  option is that perhaps &lt;span class="fixed"&gt;%eax&lt;/span&gt; has the wrong value. There  are two ways to check the contents of register in GDB. The first one is the  command &lt;span class="fixed"&gt;info register&lt;/span&gt;. This will display the contents  of all registers in hexadecimal. However, we are only interested in &lt;span class="fixed"&gt;%eax&lt;/span&gt; at this point. To just display &lt;span class="fixed"&gt;%eax&lt;/span&gt; we can do &lt;span class="fixed"&gt;print/$eax&lt;/span&gt; to print  it in hexadecimal, or do &lt;span class="fixed"&gt;print/d $eax&lt;/span&gt; to print it in  decimal. Notice that in GDB, registers are prefixed with dollar signs rather  than percent signs. Your screen should have this on it:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;(gdb) print/d $eax&lt;br /&gt;$1 = 3&lt;br /&gt;(gdb)&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;This means that the result of your first inquiry is 3. Every  inquiry you make will be assigned a number prefixed with a dollar sign. Now, if  you look back into the code, you will find that 3 is the first number in the  list of numbers to search through. If you step through the loop a few more  times, you will find that in every loop iteration &lt;span class="fixed"&gt;%eax&lt;/span&gt;  has the number 3. This is not what should be happening. &lt;span class="fixed"&gt;%eax&lt;/span&gt; should go to the next value in the list in every  iteration.&lt;/p&gt; &lt;p class="para"&gt;Okay, now we know that &lt;span class="fixed"&gt;%eax&lt;/span&gt; is being  loaded with the same value over and over again. Let's search to see where &lt;span class="fixed"&gt;%eax&lt;/span&gt; is being loaded from. The line of code is this:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt; movl data_items(,%edi,4), %eax&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;So, step until this line of code is ready to execute. Now, this  code depends on two values &lt;span class="fixed"&gt;- data_items&lt;/span&gt; and &lt;span class="fixed"&gt;%edi. data_items&lt;/span&gt; is a symbol, and therefore constant. It's a  good idea to check your source code to make sure the label is in &lt;a name="480"&gt;&lt;/a&gt;&lt;a name="IDX-293"&gt;&lt;/a&gt;front of the right data, but in our case it is.  Therefore, we need to look at &lt;span class="fixed"&gt;%edi&lt;/span&gt;. So, we need to  print it out. It will look like this:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;(gdb) print/d $edi&lt;br /&gt;$2 = 0&lt;br /&gt;(gdb)&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;This indicates that &lt;span class="fixed"&gt;%edi&lt;/span&gt; is set to zero,  which is why it keeps on loading the first element of the array. This should  cause you to ask yourself two questions - what is the purpose of &lt;span class="fixed"&gt;%edi&lt;/span&gt;, and how should its value be changed? To answer the  first question, we just need to look in the comments. &lt;span class="fixed"&gt;%edi&lt;/span&gt; is holding the current index of &lt;span class="fixed"&gt;data_items&lt;/span&gt;. Since our search is a sequential search through  the list of numbers in &lt;span class="fixed"&gt;data_items&lt;/span&gt;, it would make sense  that &lt;span class="fixed"&gt;%edi&lt;/span&gt; should be incremented with every loop  iteration.&lt;/p&gt; &lt;p class="para"&gt;Scanning the code, there is no code which alters &lt;span class="fixed"&gt;%edi&lt;/span&gt; at all. Therefore, we should add a line to increment  &lt;span class="fixed"&gt;%edi&lt;/span&gt; at the beginning of every loop iteration. This  happens to be exactly the line we tossed out at the beginning. Assembling,  linking, and running the program again will show that it now works  correctly.&lt;/p&gt; &lt;p class="last-para"&gt;Hopefully this exercise provided some insight into using GDB  to help you find errors in your programs.&lt;/p&gt;&lt;h2 class="first-section-title"&gt;&lt;a name="481"&gt;&lt;/a&gt;&lt;a name="ap06lev1sec2"&gt;&lt;/a&gt;Breakpoints and Other GDB Features&lt;/h2&gt; &lt;p class="first-para"&gt;The program we entered in the last section had an infinite  loop, and could be easily stopped using control-c. Other programs may simply  abort or finish with errors. In these cases, control-c doesn't help, because by  the time you press control-c, the program is already finished. To fix this, you  need to set &lt;i class="emphasis"&gt;breakpoints.&lt;/i&gt; A breakpoint is a place in the  source code that you have marked to indicate to the debugger that it should stop  the program when it hits that point.&lt;/p&gt; &lt;p class="para"&gt;To set breakpoints you have to set them up before you run the  program. Before issuing the &lt;span class="fixed"&gt;run&lt;/span&gt; command, you can set up  breakpoints using the &lt;span class="fixed"&gt;break&lt;/span&gt; command. &lt;a name="482"&gt;&lt;/a&gt;&lt;a name="IDX-294"&gt;&lt;/a&gt;For example, to break on line 27, issue the command &lt;span class="fixed"&gt;break 27&lt;/span&gt;. Then, when the program crosses line 27, it will  stop running, and print out the current line and instruction. You can then step  through the program from that point and examine registers and memory. To look at  the lines and line numbers of your program, you can simply use the command &lt;span class="fixed"&gt;1&lt;/span&gt;. This will print out your program with line numbers a  screen at a time.&lt;/p&gt; &lt;p class="para"&gt;When dealing with functions, you can also break on the function  names. For example, in the factorial program in &lt;span class="chapterjump"&gt;Chapter 4&lt;/span&gt;, we could set a breakpoint  for the factorial function by typing in &lt;span class="fixed"&gt;break  factorial&lt;/span&gt;. This will cause the debugger to break immediately after the  function call and the function setup (it skips the pushing of &lt;span class="fixed"&gt;%ebp&lt;/span&gt; and the copying of &lt;span class="fixed"&gt;%esp&lt;/span&gt;).&lt;/p&gt; &lt;p class="para"&gt;When stepping through code, you often don't want to have to step  through every instruction of every function. Well-tested functions are usually a  waste of time to step through except on rare occasion. Therefore, if you use the  &lt;span class="fixed"&gt;nexti&lt;/span&gt; command instead of the &lt;span class="fixed"&gt;stepi&lt;/span&gt; command, GDB will wait until completion of the function  before going on. Otherwise, with &lt;span class="fixed"&gt;stepi&lt;/span&gt;, GDB would step  you through every instruction within every called function.&lt;/p&gt; &lt;table class="warning" border="0" cellpadding="0" cellspacing="0"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td class="admon-check" valign="top"&gt;&lt;br /&gt;&lt;/td&gt; &lt;td class="admon-title" valign="top"&gt;Warning &lt;/td&gt; &lt;td class="admon-body" valign="top"&gt; &lt;p class="first-para"&gt;One problem that GDB has is with handling interrupts. Often  times GDB will miss the instruction that immediately follows an interrupt. The  instruction is actually executed, but GDB doesn't step through it. This should  not be a problem - just be aware that it may happen.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;div class="appendix"&gt;&lt;a name="ap06"&gt;&lt;/a&gt; &lt;div class="section"&gt; &lt;h2 class="first-section-title"&gt;&lt;a name="483"&gt;&lt;/a&gt;&lt;a name="ap06lev1sec3"&gt;&lt;/a&gt;GDB  Quick-Reference&lt;/h2&gt; &lt;p class="first-para"&gt;This quick-reference table is copyright 2002 Robert M.  Dondero, Jr., and is used by permission in this book. Parameters listed in  brackets are optional.&lt;/p&gt;&lt;a name="484"&gt;&lt;/a&gt;&lt;a name="IDX-295"&gt;&lt;/a&gt; &lt;div class="table"&gt;&lt;a name="485"&gt;&lt;/a&gt;&lt;a name="ap06table01"&gt;&lt;/a&gt;&lt;span class="table-title"&gt;&lt;span class="table-titlelabel"&gt;Table F-1: &lt;/span&gt;Common GDB  Debugging Commands&lt;/span&gt;  &lt;table border="1"&gt; &lt;thead&gt; &lt;tr valign="top"&gt; &lt;th class="th" scope="col" colspan="2" align="left" valign="top"&gt; &lt;p class="table-para"&gt;&lt;b class="bold"&gt;Miscellaneous&lt;/b&gt; &lt;/p&gt;&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt; &lt;tbody&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;quit&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;Exit GDB&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;help [cmd]&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;Print description of debugger command &lt;span class="fixed"&gt;cmd&lt;/span&gt;. Without &lt;span class="fixed"&gt;cmd&lt;/span&gt;, prints a list of  topics.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;directory [dir1] [dir2] ...&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;Add directories &lt;span class="fixed"&gt;dir1&lt;/span&gt;, &lt;span class="fixed"&gt;dir2&lt;/span&gt;, etc. to the list of directories searched for source  files.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt; &lt;table border="1"&gt; &lt;thead&gt; &lt;tr valign="top"&gt; &lt;th class="th" scope="col" colspan="2" align="left" valign="top"&gt; &lt;p class="table-para"&gt;&lt;b class="bold"&gt;Running the Program&lt;/b&gt; &lt;/p&gt;&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt; &lt;tbody&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;run [arg1] [arg2] ...&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;Run the program with command line arguments &lt;span class="fixed"&gt;arg1&lt;/span&gt;, &lt;span class="fixed"&gt;arg2&lt;/span&gt;, etc.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;set args arg1 [arg2] ...&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;Set the program's command-line arguments to &lt;span class="fixed"&gt;arg1&lt;/span&gt;, &lt;span class="fixed"&gt;arg2&lt;/span&gt;, etc.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;show args&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;Print the program's command-line  arguments.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt; &lt;table border="1"&gt; &lt;thead&gt; &lt;tr valign="top"&gt; &lt;th class="th" scope="col" colspan="2" align="left" valign="top"&gt; &lt;p class="table-para"&gt;&lt;b class="bold"&gt;Using Breakpoints&lt;/b&gt; &lt;/p&gt;&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt; &lt;tbody&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;info breakpoints&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;Print a list of all breakpoints and their numbers  (breakpoint numbers are used for other breakpoint commands).&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;break &lt;i class="emphasis"&gt;linenum&lt;/i&gt; &lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;Set a breakpoint at line number &lt;i class="emphasis"&gt;linenum.&lt;/i&gt; &lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;break &lt;i class="emphasis"&gt;*addr&lt;/i&gt; &lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;Set a breakpoint at memory address &lt;i class="emphasis"&gt;addr.&lt;/i&gt; &lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;break &lt;i class="emphasis"&gt;fn&lt;/i&gt; &lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;Set a breakpoint at the beginning of function &lt;i class="emphasis"&gt;fn.&lt;/i&gt; &lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;condition &lt;i class="emphasis"&gt;bpnum expr&lt;/i&gt; &lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;Break at breakpoint &lt;i class="emphasis"&gt;bpnum&lt;/i&gt; only if  expression &lt;i class="emphasis"&gt;expr&lt;/i&gt; is non-zero.&lt;/p&gt;&lt;a name="486"&gt;&lt;/a&gt;&lt;a name="IDX-296"&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;command [&lt;i class="emphasis"&gt;bpnum&lt;/i&gt;] &lt;i class="emphasis"&gt;cmd1&lt;/i&gt; [&lt;i class="emphasis"&gt;cmd2&lt;/i&gt;] ...&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;Execute commands &lt;i class="emphasis"&gt;cmd1, cmd2,&lt;/i&gt; etc.  whenever breakpoint &lt;i class="emphasis"&gt;bpnum&lt;/i&gt; (or the current breakpoint) is  hit.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;Continue&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;Continue executing the program.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;Kill&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;Stop executing the program.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;delete [&lt;i class="emphasis"&gt;bpnum1&lt;/i&gt;] [&lt;i class="emphasis"&gt;bpnum2&lt;/i&gt;] ...&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;Delete breakpoints &lt;i class="emphasis"&gt;bpnuml, bpnum2,&lt;/i&gt;  etc., or all breakpoints if none specified.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;clear &lt;i class="emphasis"&gt;*addr&lt;/i&gt; &lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;Clear the breakpoint at memory address &lt;i class="emphasis"&gt;addr.&lt;/i&gt; &lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;clear [&lt;i class="emphasis"&gt;fn&lt;/i&gt;]&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;Clear the breakpoint at function &lt;i class="emphasis"&gt;fn&lt;/i&gt;,  or the current breakpoint.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;clear &lt;i class="emphasis"&gt;linenum&lt;/i&gt; &lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;Clear the breakpoint at line number &lt;i class="emphasis"&gt;linenum.&lt;/i&gt; &lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;disable [&lt;i class="emphasis"&gt;bpnum1&lt;/i&gt;] [&lt;i class="emphasis"&gt;bpnum2&lt;/i&gt;] ...&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;Disable breakpoints &lt;i class="emphasis"&gt;bpnum1, bpnum2,&lt;/i&gt;  etc., or all breakpoints if none specified.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;enable [&lt;i class="emphasis"&gt;bpnum1&lt;/i&gt;] [&lt;i class="emphasis"&gt;bpnum2&lt;/i&gt;] ...&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;Enable breakpoints &lt;i class="emphasis"&gt;bpnum1, bpnum2,&lt;/i&gt;  etc., or all breakpoints if none specified.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt; &lt;table border="1"&gt; &lt;thead&gt; &lt;tr valign="top"&gt; &lt;th class="th" scope="col" colspan="2" align="left" valign="top"&gt; &lt;p class="table-para"&gt;&lt;b class="bold"&gt;Stepping through the Program&lt;/b&gt;  &lt;/p&gt;&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt; &lt;tbody&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;nexti&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;"Step over" the next instruction (doesn't follow function  calls).&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;stepi&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;"Step into" the next instruction (follows function  calls).&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;finish&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;"Step out" of the current  function.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt; &lt;table border="1"&gt; &lt;thead&gt; &lt;tr valign="top"&gt; &lt;th class="th" scope="col" colspan="2" align="left" valign="top"&gt; &lt;p class="table-para"&gt;&lt;b class="bold"&gt;Examining Registers and Memory&lt;/b&gt;  &lt;/p&gt;&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt; &lt;tbody&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;info registers&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;Print the contents of all registers.&lt;/p&gt;&lt;a name="487"&gt;&lt;/a&gt;&lt;a name="IDX-297"&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;print/&lt;i class="emphasis"&gt;f $reg&lt;/i&gt; &lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;Print the contents of register &lt;i class="emphasis"&gt;reg&lt;/i&gt;  using format &lt;i class="emphasis"&gt;f&lt;/i&gt;. The format can be x (hexadecimal), u  (unsigned decimal), o (octal), a(address), c (character), or f (floating  point).&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;x/&lt;i class="emphasis"&gt;rsf addr&lt;/i&gt; &lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;Print the contents of memory address &lt;i class="emphasis"&gt;addr&lt;/i&gt; using repeat count &lt;i class="emphasis"&gt;r&lt;/i&gt;, size &lt;i class="emphasis"&gt;s,&lt;/i&gt; and format &lt;i class="emphasis"&gt;f&lt;/i&gt;. Repeat count defaults  to 1 if not specified. Size can be b (byte), h (halfword), w (word), or g  (double word). Size defaults to word if not specified. Format is the same as for  print, with the additions of s (string) and i (instruction).&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;info display&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;Shows a numbered list of expressions set up to display  automatically at each break.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;display/&lt;i class="emphasis"&gt;f $reg&lt;/i&gt; &lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;At each break, print the contents of register &lt;i class="emphasis"&gt;reg&lt;/i&gt; using format &lt;i class="emphasis"&gt;f&lt;/i&gt;.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;display/&lt;i class="emphasis"&gt;s&lt;/i&gt;i addr&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;At each break, print the contents of memory address &lt;i class="emphasis"&gt;addr&lt;/i&gt; using size &lt;i class="emphasis"&gt;s&lt;/i&gt; (same options as for  the x command).&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;display/&lt;i class="emphasis"&gt;ss&lt;/i&gt; addr&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;At each break, print the string of size &lt;i class="emphasis"&gt;s&lt;/i&gt; that begins in memory address &lt;i class="emphasis"&gt;addr.&lt;/i&gt;  &lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;undisplay &lt;i class="emphasis"&gt;displaynum&lt;/i&gt; &lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;Remove &lt;i class="emphasis"&gt;displaynum&lt;/i&gt; from the display  list.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt; &lt;table border="1"&gt; &lt;thead&gt; &lt;tr valign="top"&gt; &lt;th class="th" scope="col" colspan="2" align="left" valign="top"&gt; &lt;p class="table-para"&gt;&lt;b class="bold"&gt;Examining the Call Stack&lt;/b&gt;  &lt;/p&gt;&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt; &lt;tbody&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;where&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;Print the call stack.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;backtrace&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;Print the call stack.&lt;/p&gt;&lt;a name="488"&gt;&lt;/a&gt;&lt;a name="IDX-298"&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;frame&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;Print the top of the call stack.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;up&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;Move the context toward the bottom of the call  stack.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;down&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;Move the context toward the top of the call  stack.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8901974503278002812-3226452148093871097?l=programminggroundup.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://programminggroundup.blogspot.com/feeds/3226452148093871097/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8901974503278002812&amp;postID=3226452148093871097' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8901974503278002812/posts/default/3226452148093871097'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8901974503278002812/posts/default/3226452148093871097'/><link rel='alternate' type='text/html' href='http://programminggroundup.blogspot.com/2007/01/appendix-f-using-gdb-debugger.html' title='Appendix F: Using the GDB Debugger'/><author><name>Admin</name><uri>http://www.blogger.com/profile/13783659974416042562</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8901974503278002812.post-2275636482506732590</id><published>2007-01-31T19:48:00.000-08:00</published><updated>2007-01-31T19:51:18.702-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='assembly language idioms'/><category scheme='http://www.blogger.com/atom/ns#' term='x86'/><category scheme='http://www.blogger.com/atom/ns#' term='asm'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='assembly language'/><title type='text'>Appendix E: C Idioms in Assembly Language</title><content type='html'>&lt;div class="highlights"&gt; &lt;p class="first-para"&gt;This appendix is for C programmers learning assembly  language. It is meant to give a general idea about how C constructs can be  implemented in assembly language.&lt;/p&gt;&lt;/div&gt; &lt;div class="section"&gt; &lt;h2 class="sect2-title"&gt;&lt;a name="455"&gt;&lt;/a&gt;&lt;a name="ap05lev1sec1"&gt;&lt;/a&gt;If Statement&lt;/h2&gt; &lt;p class="first-para"&gt;In C, an if statement consists of three parts - the  condition, the true branch, and the false branch. However, since assembly  language is not a block structured language, you have to work a little to  implement the block-like nature of C. For example, look at the following C  code:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;if (a == b)&lt;br /&gt;{&lt;br /&gt;/* True Branch Code Here */&lt;br /&gt;}&lt;br /&gt;else&lt;br /&gt;{&lt;br /&gt;/* False Branch Code Here */&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;/* At This Point, Reconverge */&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;In assembly language, this can be rendered as:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt; #Move a and b into registers for comparison&lt;br /&gt;movl a, %eax&lt;br /&gt;movl b, %ebx&lt;br /&gt;&lt;br /&gt;#Compare&lt;br /&gt;cmpl %eax, %ebx&lt;br /&gt;&lt;br /&gt;#If True, go to true branch&lt;br /&gt;je true_branch&lt;a name="456"&gt;&lt;/a&gt;&lt;a name="IDX-278"&gt;&lt;/a&gt;&lt;br /&gt;false_branch:  #This label is unnecessary,&lt;br /&gt;              #only here for documentation&lt;br /&gt;#False Branch Code Here&lt;br /&gt;&lt;br /&gt;#Jump to recovergence point&lt;br /&gt;jmp reconverge&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;true_branch:&lt;br /&gt;#True Branch Code Here&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;reconverge:&lt;br /&gt;#Both branches recoverge to this point&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;As you can see, since assembly language is linear, the blocks have  to jump around each other. Recovergence is handled by the programmer, not the  system.&lt;/p&gt; &lt;p class="last-para"&gt;A case statement is written just like a sequence of if  statements.&lt;/p&gt;&lt;div class="section"&gt; &lt;h2 class="first-section-title"&gt;&lt;a name="457"&gt;&lt;/a&gt;&lt;a name="ap05lev1sec2"&gt;&lt;/a&gt;Function  Call&lt;/h2&gt; &lt;p class="first-para"&gt;A function call in assembly language simply requires pushing  the arguments to the function onto the stack in &lt;i class="emphasis"&gt;reverse&lt;/i&gt;  order, and issuing a &lt;span class="fixed"&gt;call&lt;/span&gt; instruction. After calling,  the arguments are then popped back off of the stack. For example, consider the C  code:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt; printf("The number is %d", 88);&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;In assembly language, this would be rendered as:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt; .section .data&lt;br /&gt;text_string:&lt;br /&gt;.ascii "The number is %d\0"&lt;a name="458"&gt;&lt;/a&gt;&lt;a name="IDX-279"&gt;&lt;/a&gt;&lt;br /&gt;.section .text&lt;br /&gt;pushl $88&lt;br /&gt;pushl $text_string&lt;br /&gt;call  printf&lt;br /&gt;popl  %eax&lt;br /&gt;popl  %eax      #%eax is just a dummy variable,&lt;br /&gt;                #nothing is actually being done&lt;br /&gt;                #with the value. You can also&lt;br /&gt;                #directly re-adjust %esp to the&lt;br /&gt;                #proper location.&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="appendix"&gt;&lt;a name="ap05"&gt;&lt;/a&gt; &lt;div class="section"&gt; &lt;h2 class="first-section-title"&gt;&lt;a name="459"&gt;&lt;/a&gt;&lt;a name="ap05lev1sec3"&gt;&lt;/a&gt;Variables  and Assignment&lt;/h2&gt; &lt;p class="first-para"&gt;Global and static variables are declared using &lt;span class="fixed"&gt;.data&lt;/span&gt; or &lt;span class="fixed"&gt;.bss&lt;/span&gt; entries. Local  variables are declared by reserving space on the stack at the beginning of the  function. This space is given back at the end of the function.&lt;/p&gt; &lt;p class="para"&gt;Interestingly, global variables are accessed differently than  local variables in assembly language. Global variables are accessed using direct  addressing, while local variables are accessed using base pointer addressing.  For example, consider the following C code:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;int my_global_var;&lt;br /&gt;&lt;br /&gt;int foo()&lt;br /&gt;{&lt;br /&gt;int my_local_var;&lt;br /&gt;&lt;br /&gt;my_local_var = 1;&lt;br /&gt;my_global_var = 2;&lt;br /&gt;&lt;br /&gt;return 0;&lt;br /&gt;}&lt;br /&gt;&lt;a name="460"&gt;&lt;/a&gt;&lt;a name="IDX-280"&gt;&lt;/a&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;This would be rendered in assembly language as:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt; .section .data&lt;br /&gt;.lcomm my_global_var, 4&lt;br /&gt;&lt;br /&gt;.type foo, @function&lt;br /&gt;foo:&lt;br /&gt;pushl %ebp            #Save old base pointer&lt;br /&gt;movl  %esp, $ebp      #make stack pointer base pointer&lt;br /&gt;subl  $4, %esp        #Make room for my_local_var&lt;br /&gt;.equ my_local_var, -4 #Can now use my_local_var to&lt;br /&gt;                      #find the local variable&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;movl  $1, my_local_var(%ebp)&lt;br /&gt;movl  $2, my_global_var&lt;br /&gt;&lt;br /&gt;movl  %ebp, %esp      #Clean up function and return&lt;br /&gt;popl  %ebp&lt;br /&gt;ret&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;What may not be obvious is that accessing the global variable  takes fewer machine cycles than accessing the local variable. However, that may  not matter because the stack is more likely to be in physical memory (instead of  swap) than the global variable is.&lt;/p&gt; &lt;p class="last-para"&gt;Also note that in the C programming language, after the  compiler loads a value into a register, that value will likely stay in that  register until that register is needed for something else. It may also move  registers. For example, if you have a variable &lt;span class="fixed"&gt;foo&lt;/span&gt;, it  may start on the stack, but the compiler will eventually move it into registers  for processing. If there aren't many variables in use, the value may simply stay  in the register until it is needed again. Otherwise, when that register is  needed for something else, the value, if it's changed, is copied back to its  corresponding memory location. In C, you can use the keyword &lt;span class="fixed"&gt;volatile&lt;/span&gt; to make sure all modifications and references to the  variable are done to the memory &lt;a name="461"&gt;&lt;/a&gt;&lt;a name="IDX-281"&gt;&lt;/a&gt;location  itself, rather than a register copy of it, in case other processes, threads, or  hardware may be modifying the value while your function is  running.&lt;/p&gt;&lt;div class="section"&gt; &lt;h2 class="first-section-title"&gt;&lt;a name="462"&gt;&lt;/a&gt;&lt;a name="ap05lev1sec4"&gt;&lt;/a&gt;Loops&lt;/h2&gt; &lt;p class="first-para"&gt;Loops work a lot like if statements in assembly language -  the blocks are formed by jumping around. In C, a while loop consists of a loop  body, and a test to determine whether or not it is time to exit the loop. A for  loop is exactly the same, with optional initialization and counter-increment  sections. These can simply be moved around to make a while loop.&lt;/p&gt; &lt;p class="para"&gt;In C, a while loop looks like this:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;while(a &lt; b)&lt;br /&gt;{&lt;br /&gt;/* Do stuff here */&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;/* Finished Looping */&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;This can be rendered in assembly language like this:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;loop_begin:&lt;br /&gt;movl  a, %eax&lt;br /&gt;movl  b, %ebx&lt;br /&gt;cmpl  %eax, %ebx&lt;br /&gt;jge   loop_end&lt;br /&gt;&lt;br /&gt;loop_body:&lt;br /&gt;#Do stuff here&lt;br /&gt;&lt;br /&gt;jmp loop_begin&lt;br /&gt;&lt;br /&gt;loop_end:&lt;br /&gt;#Finished looping&lt;br /&gt;&lt;a name="463"&gt;&lt;/a&gt;&lt;a name="IDX-282"&gt;&lt;/a&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;The x86 assembly language has some direct support for looping as  well. The &lt;span class="fixed"&gt;%ecx&lt;/span&gt; register can be used as a counter that  &lt;i class="emphasis"&gt;ends&lt;/i&gt; with zero. The &lt;span class="fixed"&gt;loop&lt;/span&gt;  instruction will decrement &lt;span class="fixed"&gt;%ecx&lt;/span&gt; and jump to a specified  address unless &lt;span class="fixed"&gt;%ecx&lt;/span&gt; is zero. For example, if you wanted  to execute a statement 100 times, you would do this in C:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt; for(i=0; i &lt; 100; i++)&lt;br /&gt;{&lt;br /&gt; /* Do process here */&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;In assembly language it would be written like this:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;loop_initialize:&lt;br /&gt;movl $100, %ecx&lt;br /&gt;loop_begin:&lt;br /&gt;#&lt;br /&gt;#Do Process Here&lt;br /&gt;#&lt;br /&gt;&lt;br /&gt;#Decrement %ecx and loops if not zero&lt;br /&gt;loop loop_begin&lt;br /&gt;&lt;br /&gt;rest_of_program:&lt;br /&gt;#Continues on to here&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;One thing to notice is that the &lt;span class="fixed"&gt;loop&lt;/span&gt;  instruction &lt;i class="emphasis"&gt;requires you to be counting backwards to zero.&lt;/i&gt;  If you need to count forwards or use another ending number, you should use the  loop form which does not include the &lt;span class="fixed"&gt;loop&lt;/span&gt;  instruction.&lt;/p&gt; &lt;p class="last-para"&gt;For really tight loops of character string operations, there  is also the &lt;span class="fixed"&gt;rep&lt;/span&gt; instruction, but we will leave learning  about that as an exercise to the reader.&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="section"&gt; &lt;h2 class="first-section-title"&gt;&lt;a name="464"&gt;&lt;/a&gt;&lt;a name="ap05lev1sec5"&gt;&lt;/a&gt;Structs&lt;/h2&gt; &lt;p class="first-para"&gt;Structs are simply descriptions of memory blocks. For  example, in C you can say:&lt;/p&gt;&lt;a name="465"&gt;&lt;/a&gt;&lt;a name="IDX-283"&gt;&lt;/a&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;struct person {&lt;br /&gt;char firstname[40];&lt;br /&gt;char lastname[40];&lt;br /&gt;int age;&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;This doesn't do anything by itself, except give you ways of  intelligently using 84 bytes of data. You can do basically the same thing using  &lt;span class="fixed"&gt;.equ&lt;/span&gt; directives in assembly language. Like this:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt; .equ PERSON_SIZE, 84&lt;br /&gt;.equ PERSON_FIRSTNAME_OFFSET, 0&lt;br /&gt;.equ PERSON_LASTNAME_OFFSET, 40&lt;br /&gt;.equ PERSON_AGE_OFFSET, 80&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;When you declare a variable of this type, all you are doing is  reserving 84 bytes of space. So, if you have this in C:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;void foo()&lt;br /&gt;{&lt;br /&gt;struct person p;&lt;br /&gt;&lt;br /&gt;/* Do stuff here */&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;In assembly language you would have:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;foo:&lt;br /&gt;#Standard header beginning&lt;br /&gt;pushl %ebp&lt;br /&gt;movl %esp, %ebp&lt;br /&gt;&lt;br /&gt;#Reserve our local variable&lt;br /&gt;subl $PERSON_SIZE, %esp&lt;br /&gt;#This is the variable's offset from %ebp&lt;a name="466"&gt;&lt;/a&gt;&lt;a name="IDX-284"&gt;&lt;/a&gt;&lt;br /&gt;.equ P_VAR, 0 - PERSON_SIZE&lt;br /&gt;&lt;br /&gt;#Do Stuff Here&lt;br /&gt;&lt;br /&gt;#Standard function ending&lt;br /&gt;movl %ebp, %esp&lt;br /&gt;popl %ebp&lt;br /&gt;ret&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;To access structure members, you just have to use base pointer  addressing with the offsets defined above. For example, in C you could set the  person's age like this:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt; p.age  =  30;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;In assembly language it would look like this:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt; movl $30, P_VAR + PERSON_AGE_OFFSET(%ebp)&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;h2 class="first-section-title"&gt;&lt;a name="467"&gt;&lt;/a&gt;&lt;a name="ap05lev1sec6"&gt;&lt;/a&gt;Pointers&lt;/h2&gt; &lt;p class="first-para"&gt;Pointers are very easy. Remember, pointers are simply the  address that a value resides at. Let's start by taking a look at global  variables. For example:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;int global_data = 30;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;In assembly language, this would be:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt; .section .data&lt;br /&gt;global_data:&lt;br /&gt;.long 30&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;Taking the address of this data in C:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt; a = &amp;global_data;&lt;br /&gt;&lt;a name="468"&gt;&lt;/a&gt;&lt;a name="IDX-285"&gt;&lt;/a&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;Taking the address of this data in assembly language:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt; movl $global_data, %eax&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;You see, with assembly language, you are almost always accessing  memory through pointers. That's what direct addressing is. To get the pointer  itself, you just have to go with immediate mode addressing.&lt;/p&gt; &lt;p class="para"&gt;Local variables are a little more difficult, but not much. Here is  how you take the address of a local variable in C:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;void foo()&lt;br /&gt;{&lt;br /&gt;int a;&lt;br /&gt;int *b;&lt;br /&gt;&lt;br /&gt;a = 30;&lt;br /&gt;&lt;br /&gt;b = &amp;a;&lt;br /&gt;&lt;br /&gt;*b = 44;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;The same code in assembly language:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;foo:&lt;br /&gt;#Standard opening&lt;br /&gt;pushl %ebp&lt;br /&gt;movl  %esp, %ebp&lt;br /&gt;&lt;br /&gt;#Reserve two words of memory&lt;br /&gt;subl  $8, $esp&lt;br /&gt;.equ A_VAR, -4&lt;br /&gt;.equ B_VAR, -8&lt;br /&gt;&lt;br /&gt;#a = 30&lt;a name="469"&gt;&lt;/a&gt;&lt;a name="IDX-286"&gt;&lt;/a&gt;&lt;br /&gt;movl $30, A_VAR(%ebp)&lt;br /&gt;&lt;br /&gt;#b = &amp;a&lt;br /&gt;movl $A_VAR, B_VAR(%ebp)&lt;br /&gt;addl %ebp, B_VAR(%ebp)&lt;br /&gt;&lt;br /&gt;#*b = 30&lt;br /&gt;movl B_VAR(%ebp), %eax&lt;br /&gt;movl $30, (%eax)&lt;br /&gt;&lt;br /&gt;#Standard closing&lt;br /&gt;movl %ebp, %esp&lt;br /&gt;popl %ebp&lt;br /&gt;ret&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;As you can see, to take the address of a local variable, the  address has to be computed the same way the computer computes the addresses in  base pointer addressing. There is an easier way - the processor provides the  instruction &lt;span class="fixed"&gt;leal&lt;/span&gt;, which stands for "load effective  address". This lets the computer compute the address, and then load it wherever  you want. So, we could just say:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt; #b = &amp;amp;a&lt;br /&gt;leal A_VAR(%ebp), %eax&lt;br /&gt;movl %eax, B_VAR(%ebp)&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="last-para"&gt;It's the same number of lines, but a little cleaner. Then, to  use this value, you simply have to move it to a general-purpose register and use  indirect addressing, as shown in the example above.&lt;/p&gt;&lt;div class="appendix"&gt;&lt;a name="ap05"&gt;&lt;/a&gt; &lt;div class="section"&gt; &lt;h2 class="first-section-title"&gt;&lt;a name="470"&gt;&lt;/a&gt;&lt;a name="ap05lev1sec7"&gt;&lt;/a&gt;Getting  GCC to Help&lt;/h2&gt; &lt;p class="first-para"&gt;One of the nice things about GCC is its ability to spit out  assembly language code. To convert a C language file to assembly, you can simply  do:&lt;/p&gt;&lt;a name="471"&gt;&lt;/a&gt;&lt;a name="IDX-287"&gt;&lt;/a&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;gcc -S file.c&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;The output will be in &lt;span class="fixed"&gt;file.s.&lt;/span&gt; It's not  the most readable output - most of the variable names have been removed and  replaced either with numeric stack locations or references to  automatically-generated labels. To start with, you probably want to turn off  optimizations with &lt;span class="fixed"&gt;-O0&lt;/span&gt; so that the assembly language  output will follow your source code better.&lt;/p&gt; &lt;p class="para"&gt;Something else you might notice is that GCC reserves more stack  space for local variables than we do, and then AND's %&lt;span class="fixed"&gt;esp&lt;/span&gt; &lt;sup&gt;[&lt;a href="#ftn.N40" name="N40"&gt;1&lt;/a&gt;]&lt;/sup&gt; This is to  increase memory and cache efficiency by double-word aligning variables.&lt;/p&gt; &lt;p class="para"&gt;Finally, at the end of functions, we usually do the following  instructions to clean up the stack before issuing a &lt;span class="fixed"&gt;ret&lt;/span&gt;  instruction:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt; movl %ebp, %esp&lt;br /&gt;popl %ebp&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;However, GCC output will usually just include the instruction  &lt;span class="fixed"&gt;leave.&lt;/span&gt; This instruction is simply the combination of  the above two instructions. We do not use &lt;span class="fixed"&gt;leave&lt;/span&gt; in this  text because we want to be clear about exactly what is happening at the  processor level.&lt;/p&gt; &lt;p class="para"&gt;I encourage you to take a C program you have written and compile  it to assembly language and trace the logic. Then, add in optimizations and try  again. See how the compiler chose to rearrange your program to be more  optimized, and try to figure out why it chose the arrangement and instructions  it did.&lt;/p&gt;&lt;a name="472"&gt;&lt;/a&gt;&lt;a name="IDX-288"&gt;&lt;/a&gt;&lt;/div&gt; &lt;div class="footnotes"&gt; &lt;div class="footnote"&gt; &lt;p&gt;&lt;sup&gt;[&lt;a href="#N40" name="ftn.N40"&gt;1&lt;/a&gt;]&lt;/sup&gt;Note that different versions of  GCC do this differently.&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;pre class="literallayout"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;pre class="literallayout"&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8901974503278002812-2275636482506732590?l=programminggroundup.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://programminggroundup.blogspot.com/feeds/2275636482506732590/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8901974503278002812&amp;postID=2275636482506732590' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8901974503278002812/posts/default/2275636482506732590'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8901974503278002812/posts/default/2275636482506732590'/><link rel='alternate' type='text/html' href='http://programminggroundup.blogspot.com/2007/01/appendix-e-c-idioms-in-assembly.html' title='Appendix E: C Idioms in Assembly Language'/><author><name>Admin</name><uri>http://www.blogger.com/profile/13783659974416042562</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8901974503278002812.post-3588446140349407570</id><published>2007-01-31T19:47:00.000-08:00</published><updated>2007-01-31T19:48:03.282-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='table of ascii'/><category scheme='http://www.blogger.com/atom/ns#' term='x86'/><category scheme='http://www.blogger.com/atom/ns#' term='asm'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='assembly language'/><title type='text'>Appendix D: Table of ASCII Codes</title><content type='html'>&lt;p class="para"&gt;To use this table, simply find the character or escape that you  want the code for, and add the number on the left and the top.&lt;/p&gt;&lt;a name="451"&gt;&lt;/a&gt;&lt;a name="ap04table01"&gt;&lt;/a&gt; &lt;table class="table" border="1"&gt; &lt;caption class="table-title"&gt;&lt;span class="table-title"&gt;&lt;span class="table-titlelabel"&gt;Table D-1: &lt;/span&gt;Table of ASCII codes in decimal&lt;/span&gt;  &lt;/caption&gt; &lt;thead&gt; &lt;tr valign="top"&gt; &lt;th class="th" scope="col" align="left"&gt; &lt;/th&gt; &lt;th class="th" scope="col" align="left"&gt; &lt;p class="table-para"&gt;+0&lt;/p&gt;&lt;/th&gt; &lt;th class="th" scope="col" align="left"&gt; &lt;p class="table-para"&gt;+1&lt;/p&gt;&lt;/th&gt; &lt;th class="th" scope="col" align="left"&gt; &lt;p class="table-para"&gt;+2&lt;/p&gt;&lt;/th&gt; &lt;th class="th" scope="col" align="left"&gt; &lt;p class="table-para"&gt;+3&lt;/p&gt;&lt;/th&gt; &lt;th class="th" scope="col" align="left"&gt; &lt;p class="table-para"&gt;+4&lt;/p&gt;&lt;/th&gt; &lt;th class="th" scope="col" align="left"&gt; &lt;p class="table-para"&gt;+5&lt;/p&gt;&lt;/th&gt; &lt;th class="th" scope="col" align="left"&gt; &lt;p class="table-para"&gt;+6&lt;/p&gt;&lt;/th&gt; &lt;th class="th" scope="col" align="left"&gt; &lt;p class="table-para"&gt;+7&lt;/p&gt;&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt; &lt;tbody&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;0&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;NUL&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;SOH&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;STX&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;ETX&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;EOT&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;ENQ&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;ACK&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;BEL&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;8&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;BS&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;HT&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;LF&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;VT&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;FF&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;CR&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;SO&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;SI&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;16&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;DLE&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;DC1&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;DC2&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;DC3&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;DC4&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;NAK&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;SYN&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;ETB&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;24&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;CAN&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;EM&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;SUB&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;ESC&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;FS&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;GS&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;RS&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;US&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;32&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;!&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;"&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;#&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;$&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;%&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;&amp;&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;'&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;40&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;(&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;)&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;*&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;+&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;,&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;-&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;.&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;/&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;48&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;0&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;1&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;2&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;3&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;4&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;5&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;6&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;7&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;56&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;8&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;9&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;:&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;;&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;&lt;&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;=&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;&gt;&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;?&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;64&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;@&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;A&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;B&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;C&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;D&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;E&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;F&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;G&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;72&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;H&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;I&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;J&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;K&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;L&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;M&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;N&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;O&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;80&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;P&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;Q&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;R&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;S&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;T&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;U&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;V&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;W&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;88&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;X&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;Y&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;Z&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;[&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;\&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;]&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;^&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;_&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;96&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;'&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;a&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;b&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;c&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;d&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;e&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;f&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;g&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;104&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;h&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;i&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;j&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;k&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;l&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;m&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;n&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;o&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;112&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;p&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;q&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;r&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;s&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;t&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;u&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;v&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;w&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;120&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;x&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;y&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;z&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;{&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;|&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;}&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;~&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;DEL&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt; &lt;p class="para"&gt;ASCII is actually being phased out in favor of an international  standard known as Unicode, which allows you to display any character from any  known writing system in the world. As you may have noticed, ASCII only has  support for English characters. Unicode is much more complicated, however,  because it requires more than one byte to encode a single character. There are  several &lt;a name="452"&gt;&lt;/a&gt;&lt;a name="IDX-276"&gt;&lt;/a&gt;different methods for encoding  Unicode characters. The most common is UTF-8 and UTF-32. UTF-8 is somewhat  backwards-compatible with ASCII (it is stored the same for English characters,  but expands into multiple byte for international characters). UTF-32 simply  requires four bytes for each character rather than one. Windows® uses UTF-16,  which is a variable-length encoding which requires at least 2 bytes per  character, so it is not backwards-compatible with ASCII.&lt;/p&gt; &lt;p class="last-para"&gt;A good tutorial on internationalization issues, fonts, and  Unicode is available in a great Article by Joe Spolsky, called "The Absolute  Minimum Every Software Developer Absolutely, Positively Must Know About Unicode  and Character Sets (No Excuses!)", available online at &lt;a class="url" href="http://www.joelonsoftware.com/articles/Unicode.html" target="_top"&gt;http://www.joelonsoftware.com/articles/Unicode.html&lt;/a&gt; &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8901974503278002812-3588446140349407570?l=programminggroundup.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://programminggroundup.blogspot.com/feeds/3588446140349407570/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8901974503278002812&amp;postID=3588446140349407570' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8901974503278002812/posts/default/3588446140349407570'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8901974503278002812/posts/default/3588446140349407570'/><link rel='alternate' type='text/html' href='http://programminggroundup.blogspot.com/2007/01/appendix-d-table-of-ascii-codes.html' title='Appendix D: Table of ASCII Codes'/><author><name>Admin</name><uri>http://www.blogger.com/profile/13783659974416042562</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8901974503278002812.post-3656164337444026863</id><published>2007-01-31T19:45:00.000-08:00</published><updated>2007-01-31T19:46:54.937-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='important system calls'/><category scheme='http://www.blogger.com/atom/ns#' term='x86'/><category scheme='http://www.blogger.com/atom/ns#' term='asm'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='assembly language'/><title type='text'>Appendix C: Important System Calls</title><content type='html'>&lt;p class="para"&gt;These are some of the more important system calls to use when  dealing with Linux. For most cases, however, it is best to use library functions  rather than direct system calls, because the system calls were designed to be  minimalistic while the library functions were designed to be easy to program  with. For information about the Linux C library, see the manual at &lt;a class="url" href="http://www.gnu.org/software/libc/manual/" target="_top"&gt;http://www.gnu.org/software/libc/manual/&lt;/a&gt; &lt;/p&gt; &lt;p class="para"&gt;Remember that &lt;span class="fixed"&gt;%eax&lt;/span&gt; holds the system call  numbers, and that the return values and error codes are also stored in &lt;span class="fixed"&gt;%eax&lt;/span&gt;.&lt;/p&gt;&lt;a name="445"&gt;&lt;/a&gt;&lt;a name="ap03table01"&gt;&lt;/a&gt; &lt;table class="table" border="1"&gt; &lt;caption class="table-title"&gt;&lt;span class="table-title"&gt;&lt;span class="table-titlelabel"&gt;Table C-1: &lt;/span&gt;Important Linux System Calls&lt;/span&gt;  &lt;/caption&gt; &lt;thead&gt; &lt;tr valign="top"&gt; &lt;th class="th" scope="col" align="left"&gt; &lt;p class="table-para"&gt;&lt;b class="bold"&gt;&lt;span class="fixed"&gt;%eax&lt;/span&gt;&lt;/b&gt; &lt;/p&gt;&lt;/th&gt; &lt;th class="th" scope="col" align="left"&gt; &lt;p class="table-para"&gt;&lt;b class="bold"&gt;Name&lt;/b&gt; &lt;/p&gt;&lt;/th&gt; &lt;th class="th" scope="col" align="left"&gt; &lt;p class="table-para"&gt;&lt;b class="bold"&gt;&lt;span class="fixed"&gt;%ebx&lt;/span&gt;&lt;/b&gt; &lt;/p&gt;&lt;/th&gt; &lt;th class="th" scope="col" align="left"&gt; &lt;p class="table-para"&gt;&lt;b class="bold"&gt;&lt;span class="fixed"&gt;%ecx&lt;/span&gt;&lt;/b&gt; &lt;/p&gt;&lt;/th&gt; &lt;th class="th" scope="col" align="left"&gt; &lt;p class="table-para"&gt;&lt;b class="bold"&gt;&lt;span class="fixed"&gt;%edx&lt;/span&gt;&lt;/b&gt; &lt;/p&gt;&lt;/th&gt; &lt;th class="th" scope="col" align="left"&gt; &lt;p class="table-para"&gt;&lt;b class="bold"&gt;Notes&lt;/b&gt; &lt;/p&gt;&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt; &lt;tbody&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;1&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;exit&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;return value (int)&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;Exits the program&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;3&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;read&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;file descriptor&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;buffer start&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;buffer size (int)&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;Reads into the given buffer&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;4&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;write&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;file descriptor&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;buffer start&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;buffer size (int)&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;Writes the buffer to the file descriptor&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;5&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;open&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;null-terminate file name&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;option list&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;permission mode&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;Opens the given file. Returns the file descriptor or an  error number.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;6&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;close&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;file descriptor&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;Closes the give file descriptor&lt;/p&gt;&lt;a name="446"&gt;&lt;/a&gt;&lt;a name="IDX-272"&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;12&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;chdir&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;null-terminated directory name&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;Changes the current directory of your program.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;19&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;lseek&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;file descriptor&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;offset&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;mode&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;Repositions where you are in the given file. The mode  (called the "whence") should be 0 for absolute positioning, and 1 for relative  positioning.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;20&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;getpid&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;Returns the process ID of the current process.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;39&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;mkdir&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;null-terminated directory name&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;permission mode&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;Creates the given directory. Assumes all directories leading  up to it already exist.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;40&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;rmdir&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;null-terminated directory name&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;Removes the given directory.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;41&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;dup&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;file descriptor&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;Returns a new file descriptor pat works just like the  existing file descriptor.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;42&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;pipe&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;pipe array&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;Creates two file descriptors, where writing on one produces  data to read on the other and vice-versa. %ebx is a pointer to two words of  storage to hold the file descriptors.&lt;/p&gt;&lt;a name="447"&gt;&lt;/a&gt;&lt;a name="IDX-273"&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;45&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;brk&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;new system break&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;Sets the system break (i.e. -the end of the data section).  If the system break is 0, it simply returns the current system  break.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;54&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;ioctl&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;file descriptor&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;request&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;arguments&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;This is used to set parameters on device files. Its actual  usage varies based on the type of file or device your descriptor  references.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt; &lt;p class="para"&gt;A more complete listing of system calls, along with additional  information is available at &lt;a class="url" href="http://www.lxhp.in-berlin.de/lhpsyscal.html" target="_top"&gt;http://www.lxhp.in-berlin.de/lhpsyscal.html&lt;/a&gt; You can also get  more information about a system call by typing in &lt;span class="fixed"&gt;man 2  SYSCALLNAME&lt;/span&gt; which will return you the information about the system call  from section 2 of the UNIX manual. However, this refers to the usage of the  system call from the C programming language, and may or may not be directly  helpful.&lt;/p&gt; &lt;p class="para"&gt;For information on how system calls are implemented on Linux, see  the Linux Kernel 2.4 Internals section on how system calls are implemented at &lt;a class="url" href="http://www.faqs.org/docs/kernel_2_4/lki-2.html#ss2.11" target="_top"&gt;http://www.faqs.org/docs/kernel_2_4/lki-2.html#ss2.11&lt;/a&gt; &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8901974503278002812-3656164337444026863?l=programminggroundup.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://programminggroundup.blogspot.com/feeds/3656164337444026863/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8901974503278002812&amp;postID=3656164337444026863' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8901974503278002812/posts/default/3656164337444026863'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8901974503278002812/posts/default/3656164337444026863'/><link rel='alternate' type='text/html' href='http://programminggroundup.blogspot.com/2007/01/appendix-c-important-system-calls.html' title='Appendix C: Important System Calls'/><author><name>Admin</name><uri>http://www.blogger.com/profile/13783659974416042562</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8901974503278002812.post-7612300635539070347</id><published>2007-01-31T19:37:00.000-08:00</published><updated>2007-01-31T19:40:46.164-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='common x86 instructions'/><category scheme='http://www.blogger.com/atom/ns#' term='x86'/><category scheme='http://www.blogger.com/atom/ns#' term='asm'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='assembly language'/><title type='text'>Appendix B: Common x86 Instructions</title><content type='html'>&lt;div class="section"&gt; &lt;h2 class="sect2-title"&gt;&lt;a name="417"&gt;&lt;/a&gt;&lt;a name="ap02lev1sec1"&gt;&lt;/a&gt;Reading the  Tables&lt;/h2&gt; &lt;p class="first-para"&gt;The tables of instructions presented in this appendix  include:&lt;/p&gt; &lt;ul class="itemizedlist"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;The instruction code&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;The operands used&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;The flags used&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;A brief description of what the instruction  does&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p class="para"&gt;In the operands section, it will list the type of operands it  takes. If it takes more than one operand, each operand will be separated by a  comma. Each operand will have a list of codes which tell whether the operand can  be an immediate-mode value (I), a register (R), or a memory address (M). For  example, the &lt;span class="fixed"&gt;movl&lt;/span&gt; instruction is listed as &lt;span class="fixed"&gt;I/R/M&lt;/span&gt;, &lt;span class="fixed"&gt;R/M&lt;/span&gt;. This means that the  first operand can be any kind of value, while the second operand must be a  register or memory location. Note, however, that in x86 assembly language you  cannot have more than one operand be a memory location.&lt;/p&gt; &lt;p class="para"&gt;In the flags section, it lists the flags in the &lt;span class="fixed"&gt;%eflags&lt;/span&gt; register affected by the instruction. The following  flags are mentioned:&lt;/p&gt; &lt;p class="para"&gt;O&lt;/p&gt; &lt;ul class="simple-list"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;Overflow flag. This is set to true if the destination  operand was not large enough to hold the result of the  instruction.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p class="para"&gt;S&lt;/p&gt; &lt;ul class="simple-list"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;Sign flag. This is set to the sign of the last  result.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;a name="418"&gt;&lt;/a&gt;&lt;a name="IDX-258"&gt;&lt;/a&gt; &lt;p class="para"&gt;Z&lt;/p&gt; &lt;ul class="simple-list"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;Zero flag. This flag is set to true if the result of the  instruction is zero.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p class="para"&gt;A&lt;/p&gt; &lt;ul class="simple-list"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;Auxiliary carry flag. This flag is set for carries and  borrows between the third and fourth bit. It is not often used.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p class="para"&gt;P&lt;/p&gt; &lt;ul class="simple-list"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;Parity flag. This flag is set to true if the low byte of the  last result had an even number of 1 bits.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p class="para"&gt;C&lt;/p&gt; &lt;ul class="simple-list"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;Carry flag. Used in arithmetic to say whether or not the  result should be carried over to an additional byte. If the carry flag is set,  that usually means that the destination register could not hold the full result.  It is up to the programmer to decide on what action to take (i.e. - propogate  the result to another byte, signal an error, or ignore it  entirely).&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p class="last-para"&gt;Other flags exist, but they are much less  important.&lt;/p&gt;&lt;div class="appendix"&gt;&lt;a name="ap02"&gt;&lt;/a&gt; &lt;div class="section"&gt; &lt;h2 class="first-section-title"&gt;&lt;a name="419"&gt;&lt;/a&gt;&lt;a name="ap02lev1sec2"&gt;&lt;/a&gt;Data  Transfer Instructions&lt;/h2&gt; &lt;p class="first-para"&gt;These instructions perform little, if any computation.  Instead they are mostly used for moving data from one place to another.&lt;/p&gt;&lt;a name="420"&gt;&lt;/a&gt;&lt;a name="ap02table01"&gt;&lt;/a&gt; &lt;table class="table" border="1"&gt; &lt;caption class="table-title"&gt;&lt;span class="table-title"&gt;&lt;span class="table-titlelabel"&gt;Table B-1: &lt;/span&gt;Data Transfer Instructions&lt;/span&gt;  &lt;/caption&gt; &lt;thead&gt; &lt;tr valign="top"&gt; &lt;th class="th" scope="col" align="left"&gt; &lt;p class="table-para"&gt;&lt;b class="bold"&gt;Instruction&lt;/b&gt; &lt;/p&gt;&lt;/th&gt; &lt;th class="th" scope="col" align="left"&gt; &lt;p class="table-para"&gt;&lt;b class="bold"&gt;Operands&lt;/b&gt; &lt;/p&gt;&lt;/th&gt; &lt;th class="th" scope="col" align="left"&gt; &lt;p class="table-para"&gt;&lt;b class="bold"&gt;Affected Flags&lt;/b&gt; &lt;/p&gt;&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt; &lt;tbody&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;movl&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;I/R/M, I/R/M&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;O/S/Z/A/C&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" colspan="3" align="left" valign="top"&gt; &lt;p class="table-para"&gt;This copies a word of data from one location to another.  &lt;span class="fixed"&gt;movl %eax&lt;/span&gt;, &lt;span class="fixed"&gt;%ebx&lt;/span&gt; copies the  contents of &lt;span class="fixed"&gt;%eax&lt;/span&gt; to &lt;span class="fixed"&gt;%ebx&lt;/span&gt;  &lt;/p&gt;&lt;a name="421"&gt;&lt;/a&gt;&lt;a name="IDX-259"&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;movb&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;I/R/M, I/R/M&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;O/S/Z/A/C&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" colspan="3" align="left" valign="top"&gt; &lt;p class="table-para"&gt;Same as &lt;span class="fixed"&gt;movl&lt;/span&gt;, but operates on  individual bytes.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;leal&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;M, I/R/M&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;O/S/Z/A/C&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" colspan="3" align="left" valign="top"&gt; &lt;p class="table-para"&gt;This takes a memory location given in the standard format,  and, instead of loading the contents of the memory location, loads the computed  address. For example, &lt;span class="fixed"&gt;leal 5 (%ebp, %ecx, 1), %eax&lt;/span&gt;  loads the address computed by &lt;span class="fixed"&gt;5 + %ebp + 1*%ecx&lt;/span&gt; and  stores that in &lt;span class="fixed"&gt;%eax&lt;/span&gt; &lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;popl&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;R/M&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;O/S/Z/A/C&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" colspan="3" align="left" valign="top"&gt; &lt;p class="table-para"&gt;Pops the top of the stack into the given location. This is  equivalent to performing &lt;span class="fixed"&gt;movl (%esp), R/M&lt;/span&gt; followed by  &lt;span class="fixed"&gt;addl $4, %esp.popfl&lt;/span&gt; is a variant which pops the top of  the stack into the &lt;span class="fixed"&gt;%eflags&lt;/span&gt; register.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;pushl&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;I/R/M&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;O/S/Z/A/C&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" colspan="3" align="left" valign="top"&gt; &lt;p class="table-para"&gt;Pushes the given value onto the stack. This is the  equivalent to performing &lt;span class="fixed"&gt;subl $4, %esp&lt;/span&gt; followed by  &lt;span class="fixed"&gt;movl I/R/M, (%esp).pushfl&lt;/span&gt; is a variant which pushes the  current contents of the &lt;span class="fixed"&gt;%eflags&lt;/span&gt; register onto the &lt;b class="bold"&gt;top&lt;/b&gt; of the stack.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;xchgl&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;R/M, R/M&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;O/S/Z/A/C&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" colspan="3" align="left" valign="top"&gt; &lt;p class="table-para"&gt;Exchange the values of the given  operands.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="appendix"&gt;&lt;a name="ap02"&gt;&lt;/a&gt; &lt;div class="section"&gt; &lt;h2 class="first-section-title"&gt;&lt;a name="422"&gt;&lt;/a&gt;&lt;a name="ap02lev1sec3"&gt;&lt;/a&gt;Integer  Instructions&lt;/h2&gt; &lt;p class="first-para"&gt;These are basic calculating instructions that operate on  signed or unsigned integers.&lt;/p&gt;&lt;a name="423"&gt;&lt;/a&gt;&lt;a name="ap02table02"&gt;&lt;/a&gt; &lt;table class="table" border="1"&gt; &lt;caption class="table-title"&gt;&lt;span class="table-title"&gt;&lt;span class="table-titlelabel"&gt;Table B-2: &lt;/span&gt;Integer Instructions&lt;/span&gt; &lt;/caption&gt; &lt;thead&gt; &lt;tr valign="top"&gt; &lt;th class="th" scope="col" align="left"&gt; &lt;p class="table-para"&gt;&lt;b class="bold"&gt;Instruction&lt;/b&gt; &lt;/p&gt;&lt;/th&gt; &lt;th class="th" scope="col" align="left"&gt; &lt;p class="table-para"&gt;&lt;b class="bold"&gt;Operands&lt;/b&gt; &lt;/p&gt;&lt;/th&gt; &lt;th class="th" scope="col" align="left"&gt; &lt;p class="table-para"&gt;&lt;b class="bold"&gt;Affected Flags&lt;/b&gt; &lt;/p&gt;&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt; &lt;tbody&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;adcl&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;I/R/M, R/M&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;O/S/Z/A/P/C&lt;/p&gt;&lt;a name="424"&gt;&lt;/a&gt;&lt;a name="IDX-260"&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" colspan="3" align="left" valign="top"&gt; &lt;p class="table-para"&gt;Add with carry. Adds the carry bit and the first operand to  the second, and, if there is an overflow, sets overflow and carry to true. This  is usually used for operations larger than a machine word. The addition on the  least-significant word would take place using &lt;span class="fixed"&gt;addl&lt;/span&gt;,  while additions to the other words would used the &lt;span class="fixed"&gt;adcl&lt;/span&gt;  instruction to take the carry from the previous add into account. For the usual  case, this is not used, and &lt;span class="fixed"&gt;addl&lt;/span&gt; is used  instead.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;addl&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;I/R/M, R/M&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;O/S/Z/A/P/C&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" colspan="3" align="left" valign="top"&gt; &lt;p class="table-para"&gt;Addition. Adds the first operand to the second, storing the  result in the second. If the result is larger than the destination register, the  overflow and carry bits are set to true. This instruction operates on both  signed and unsigned integers.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;cdq&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;O/S/Z/A/P/C&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" colspan="3" align="left" valign="top"&gt; &lt;p class="table-para"&gt;Converts the &lt;span class="fixed"&gt;%eax&lt;/span&gt; word into the  double-word consisting of &lt;span class="fixed"&gt;%edx:%eax&lt;/span&gt; with sign  extension. The &lt;span class="fixed"&gt;q&lt;/span&gt; signifies that it is a &lt;i class="emphasis"&gt;quad-word.&lt;/i&gt; It's actually a double-word, but it's called a  quad-word because of the terminology used in the 16-bit days. This is usually  used before issuing an &lt;span class="fixed"&gt;idivl&lt;/span&gt; instruction.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;cmpl&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;I/R/M, R/M&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;O/S/Z/A/P/C&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" colspan="3" align="left" valign="top"&gt; &lt;p class="table-para"&gt;Compares two integers. It does this by subtracting the first  operand from the second. It discards the results, but sets the flags  accordingly. Usually used before a conditional jump.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;decl&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;R/M&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;O/S/Z/A/P&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" colspan="3" align="left" valign="top"&gt; &lt;p class="table-para"&gt;Decrements the register or memory location. Use &lt;span class="fixed"&gt;decb&lt;/span&gt; to decrement a byte instead of a word.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;divl&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;R/M&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;O/S/Z/A/P&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" colspan="3" align="left" valign="top"&gt; &lt;p class="table-para"&gt;Performs unsigned division. Divides the contents of the  double-word contained in the combined &lt;span class="fixed"&gt;%edx:%eax&lt;/span&gt;  registers by the value in the register or memory location specified. The &lt;span class="fixed"&gt;%eax&lt;/span&gt; register contains the resulting quotient, and the &lt;span class="fixed"&gt;%edx&lt;/span&gt; register contains the resulting remainder. If the  quotient is too large to fit in &lt;span class="fixed"&gt;%eax&lt;/span&gt;, it triggers a  type 0 interrupt.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;idivl&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;R/M&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;O/S/Z/A/P&lt;/p&gt;&lt;a name="425"&gt;&lt;/a&gt;&lt;a name="IDX-261"&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" colspan="3" align="left" valign="top"&gt; &lt;p class="table-para"&gt;Performs signed division. Operates just like &lt;span class="fixed"&gt;divl&lt;/span&gt; above.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;imull&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;R/M/I, R&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;O/S/Z/A/P/C&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" colspan="3" align="left" valign="top"&gt; &lt;p class="table-para"&gt;Performs signed multiplication and stores the result in the  second operand. If the second operand is left out, it is assumed to be &lt;span class="fixed"&gt;%eax&lt;/span&gt;, and the full result is stored in the double-word &lt;span class="fixed"&gt;%edx:%eax&lt;/span&gt;.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;incl&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;R/M&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;O/S/Z/A/P&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" colspan="3" align="left" valign="top"&gt; &lt;p class="table-para"&gt;Increments the given register or memory location. Use &lt;span class="fixed"&gt;incb&lt;/span&gt; to increment a byte instead of a word.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;mull&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;R/M/I, R&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;O/S/Z/A/P/C&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" colspan="3" align="left" valign="top"&gt; &lt;p class="table-para"&gt;Perform unsigned multiplication. Same rules as apply to  &lt;span class="fixed"&gt;imull&lt;/span&gt;.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;negl&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;R/M&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;O/S/Z/A/P/C&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" colspan="3" align="left" valign="top"&gt; &lt;p class="table-para"&gt;Negates (gives the two's complement inversion of) the given  register or memory location.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;sbbl&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;I/R/M, R/M&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;O/S/Z/A/P/C&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" colspan="3" align="left" valign="top"&gt; &lt;p class="table-para"&gt;Subtract with borrowing. This is used in the same way that  &lt;span class="fixed"&gt;adc&lt;/span&gt; is, except for subtraction. Normally only &lt;span class="fixed"&gt;subl&lt;/span&gt; is used.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;subl&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;I/R/M, R/M&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;O/S/Z/A/P/C&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" colspan="3" align="left" valign="top"&gt; &lt;p class="table-para"&gt;Subtract the two operands. This subtracts the first operand  from the second, and stores the result in the second operand. This instruction  can be used on both signed and unsigned  numbers.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="appendix"&gt;&lt;a name="ap02"&gt;&lt;/a&gt; &lt;div class="section"&gt; &lt;h2 class="first-section-title"&gt;&lt;a name="426"&gt;&lt;/a&gt;&lt;a name="ap02lev1sec4"&gt;&lt;/a&gt;Logic  Instructions&lt;/h2&gt; &lt;p class="first-para"&gt;These instructions operate on memory as bits instead of  words.&lt;/p&gt;&lt;a name="427"&gt;&lt;/a&gt;&lt;a name="ap02table03"&gt;&lt;/a&gt; &lt;table class="table" border="1"&gt; &lt;caption class="table-title"&gt;&lt;span class="table-title"&gt;&lt;span class="table-titlelabel"&gt;Table B-3: &lt;/span&gt;Logic Instructions&lt;/span&gt; &lt;/caption&gt; &lt;thead&gt; &lt;tr valign="top"&gt; &lt;th class="th" scope="col" align="left"&gt; &lt;p class="table-para"&gt;&lt;b class="bold"&gt;Instruction&lt;/b&gt; &lt;/p&gt;&lt;/th&gt; &lt;th class="th" scope="col" align="left"&gt; &lt;p class="table-para"&gt;&lt;b class="bold"&gt;Operands&lt;/b&gt; &lt;/p&gt;&lt;/th&gt; &lt;th class="th" scope="col" align="left"&gt; &lt;p class="table-para"&gt;&lt;b class="bold"&gt;Affected Flags&lt;/b&gt; &lt;/p&gt;&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt; &lt;tbody&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;andl&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;I/R/M, R/M&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;O/S/Z/P/C&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" colspan="3" align="left" valign="top"&gt; &lt;p class="table-para"&gt;Performs a logical and of the contents of the two operands,  and stores the result in the second operand. Sets the overflow and carry flags  to false.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;notl&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;R/M&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" colspan="3" align="left" valign="top"&gt; &lt;p class="table-para"&gt;Performs a logical not on each bit in the operand. Also  known as a one's complement.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;orl&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;I/R/M, R/M&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;O/S/Z/A/P/C&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" colspan="3" align="left" valign="top"&gt; &lt;p class="table-para"&gt;Performs a logical or between the two operands, and stores  the result in the second operand. Sets the overflow and carry flags to  false.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;rcll&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;I/&lt;span class="fixed"&gt;%c1&lt;/span&gt;, R/M&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;O/C&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" colspan="3" align="left" valign="top"&gt; &lt;p class="table-para"&gt;Rotates the given location's bits to the left the number of  times in the first operand, which is either an immediate-mode value or the  register &lt;span class="fixed"&gt;%cl&lt;/span&gt;. The carry flag is included in the  rotation, making it use 33 bits instead of 32. Also sets the overflow  flag.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;rcrl&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;I/&lt;span class="fixed"&gt;%cl&lt;/span&gt;, R/M&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;O/C&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" colspan="3" align="left" valign="top"&gt; &lt;p class="table-para"&gt;Same as above, but rotates right.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;roll&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;I/&lt;span class="fixed"&gt;%cl&lt;/span&gt;, R/M&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;O/C&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" colspan="3" align="left" valign="top"&gt; &lt;p class="table-para"&gt;Rotate bits to the left. It sets the overflow and carry  flags, but does not count the carry flag as part of the rotation. The number of  bits to roll is either specified in immediate mode or is contained in the &lt;span class="fixed"&gt;%cl&lt;/span&gt; register.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;rorl&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;I/&lt;span class="fixed"&gt;%cl&lt;/span&gt;, R/M&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;O/C&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" colspan="3" align="left" valign="top"&gt; &lt;p class="table-para"&gt;Same as above, but rotates right.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;sall&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;I/&lt;span class="fixed"&gt;%cl&lt;/span&gt;, R/M&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;C&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" colspan="3" align="left" valign="top"&gt; &lt;p class="table-para"&gt;Arithmetic shift left. The sign bit is shifted out to the  carry flag, and a zero bit is placed in the least significant bit. Other bits  are simply shifted to the left. This is the same as the regular shift left. The  number of bits to shift is either specified in immediate mode or is contained in  the &lt;span class="fixed"&gt;%cl&lt;/span&gt; register.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;sarl&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;I/&lt;span class="fixed"&gt;%cl&lt;/span&gt;, R/M&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;C&lt;/p&gt;&lt;a name="428"&gt;&lt;/a&gt;&lt;a name="IDX-262"&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" colspan="3" align="left" valign="top"&gt; &lt;p class="table-para"&gt;Arithmetic shift right. The least significant bit is shifted  out to the carry flag. The sign bit is shifted in, and kept as the sign bit.  Other bits are simply shifted to the right. The number of bits to shift is  either specified in immediate mode or is contained in the &lt;span class="fixed"&gt;%cl&lt;/span&gt; register.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;shll&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;I/&lt;span class="fixed"&gt;%cl&lt;/span&gt;, R/M&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;C&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" colspan="3" align="left" valign="top"&gt; &lt;p class="table-para"&gt;Logical shift left. This shifts all bits to the left (sign  bit is not treated specially). The leftmost bit is pushed to the carry flag. The  number of bits to shift is either specified in immediate mode or is contained in  the &lt;span class="fixed"&gt;%cl&lt;/span&gt; register.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;shrl&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;I/&lt;span class="fixed"&gt;%cl&lt;/span&gt;, R/M&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;C&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" colspan="3" align="left" valign="top"&gt; &lt;p class="table-para"&gt;Logical shift right. This shifts all bits in the register to  the right (sign bit is not treated specially). The rightmost bit is pushed to  the carry flag. The number of bits o shift is either specified in immediate mode  or is contained in the &lt;span class="fixed"&gt;%cl&lt;/span&gt; register.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;testl&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;I/R/M, R/M&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;O/S/Z/A/P/C&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" colspan="3" align="left" valign="top"&gt; &lt;p class="table-para"&gt;Does a logical and of both operands and discards the  results, but sets the flags accordingly.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;xorl&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;I/R/M, R/M&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;O/S/Z/A/P/C&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" colspan="3" align="left" valign="top"&gt; &lt;p class="table-para"&gt;Does an exclusive or on the two operands, and stores the  result in the second operand. Sets the overflow and carry flags to  false.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="appendix"&gt;&lt;a name="ap02"&gt;&lt;/a&gt; &lt;div class="section"&gt; &lt;h2 class="first-section-title"&gt;&lt;a name="429"&gt;&lt;/a&gt;&lt;a name="ap02lev1sec5"&gt;&lt;/a&gt;Flow  Control Instructions&lt;/h2&gt;&lt;a name="430"&gt;&lt;/a&gt;&lt;a name="IDX-263"&gt;&lt;/a&gt; &lt;p class="para"&gt;These instructions may alter the flow of the program.&lt;/p&gt;&lt;a name="431"&gt;&lt;/a&gt;&lt;a name="ap02table04"&gt;&lt;/a&gt; &lt;table class="table" border="1"&gt; &lt;caption class="table-title"&gt;&lt;span class="table-title"&gt;&lt;span class="table-titlelabel"&gt;Table B-4: &lt;/span&gt;Flow Control Instructions&lt;/span&gt;  &lt;/caption&gt; &lt;thead&gt; &lt;tr valign="top"&gt; &lt;th class="th" scope="col" align="left"&gt; &lt;p class="table-para"&gt;&lt;b class="bold"&gt;Instruction&lt;/b&gt; &lt;/p&gt;&lt;/th&gt; &lt;th class="th" scope="col" align="left"&gt; &lt;p class="table-para"&gt;&lt;b class="bold"&gt;Operands&lt;/b&gt; &lt;/p&gt;&lt;/th&gt; &lt;th class="th" scope="col" align="left"&gt; &lt;p class="table-para"&gt;&lt;b class="bold"&gt;Affected Flags&lt;/b&gt; &lt;/p&gt;&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt; &lt;tbody&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;call&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;destination address&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;O/S/Z/A/C&lt;/p&gt;&lt;a name="432"&gt;&lt;/a&gt;&lt;a name="IDX-264"&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" colspan="3" align="left" valign="top"&gt; &lt;p class="table-para"&gt;This pushes what would be the next value for &lt;span class="fixed"&gt;%eip&lt;/span&gt; onto the stack, and jumps to the destination address.  Used for function calls. Alternatively, the destination address can be an  asterisk followed by a register for an indirect function call. For example,  &lt;span class="fixed"&gt;call *%eax&lt;/span&gt; will call the function at the address in  &lt;span class="fixed"&gt;%eax&lt;/span&gt;.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;int&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;I&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;O/S/Z/A/C&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" colspan="3" align="left" valign="top"&gt; &lt;p class="table-para"&gt;Causes an interrupt of the given number. This is usually  used for system calls and other kernel interfaces.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left" valign="center"&gt; &lt;p class="table-para"&gt;Jcc&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left" valign="center"&gt; &lt;p class="table-para"&gt;destination address&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left" valign="center"&gt; &lt;p class="table-para"&gt;O/S/Z/A/C&lt;/p&gt;&lt;a name="433"&gt;&lt;/a&gt;&lt;a name="IDX-265"&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" colspan="3" align="left" valign="top"&gt; &lt;p class="table-para"&gt;Conditional branch. &lt;span class="fixed"&gt;cc&lt;/span&gt; is the &lt;i class="emphasis"&gt;condition code.&lt;/i&gt; Jumps to the given address if the condition  code is true (set from the previous instruction, probably a comparison).  Otherwise, goes to the next instruction. The condition codes are:&lt;/p&gt; &lt;ul class="itemizedlist"&gt;&lt;li class="first-listitem"&gt; &lt;p class="table-para"&gt;&lt;span class="fixed"&gt;[n] a [e]&lt;/span&gt; - above (unsigned greater  than). An &lt;span class="fixed"&gt;n&lt;/span&gt; can be added for "not" and an &lt;span class="fixed"&gt;e&lt;/span&gt; can be added for "or equal to"&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="table-para"&gt;&lt;span class="fixed"&gt;[n] b [e]&lt;/span&gt; - below (unsigned less  than)&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="table-para"&gt;&lt;span class="fixed"&gt;[n] e&lt;/span&gt; - equal to&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="table-para"&gt;&lt;span class="fixed"&gt;[n]z&lt;/span&gt; - zero&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="table-para"&gt;&lt;span class="fixed"&gt;[n] g [e]&lt;/span&gt; - greater than (signed  comparison)&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="table-para"&gt;&lt;span class="fixed"&gt;[n] l [e]&lt;/span&gt; - less than (signed  comparison)&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="table-para"&gt;&lt;span class="fixed"&gt;[n] c&lt;/span&gt; - carry flag set&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="table-para"&gt;&lt;span class="fixed"&gt;[n] o&lt;/span&gt; - overflow flag set&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="table-para"&gt;&lt;span class="fixed"&gt;[p] p&lt;/span&gt; - parity flag set&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="table-para"&gt;&lt;span class="fixed"&gt;[n] s&lt;/span&gt; - sign flag set&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="table-para"&gt;&lt;span class="fixed"&gt;ecxz&lt;/span&gt; - &lt;span class="fixed"&gt;%ecx&lt;/span&gt; is zero&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;jmp&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;destination address&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;O/S/Z/A/C&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" colspan="3" align="left" valign="top"&gt; &lt;p class="table-para"&gt;An unconditional jump. This simply sets &lt;span class="fixed"&gt;%eip&lt;/span&gt; to the destination address. Alternatively, the  destination address can be an asterisk followed by a register for an indirect  jump. For example, &lt;span class="fixed"&gt;jmp *%eax&lt;/span&gt; will jump to the address  in &lt;span class="fixed"&gt;%eax&lt;/span&gt;.&lt;/p&gt;&lt;a name="434"&gt;&lt;/a&gt;&lt;a name="IDX-266"&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;ret&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;O/S/Z/A/C&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" colspan="3" align="left" valign="top"&gt; &lt;p class="table-para"&gt;Pops a value off of the stack and then sets &lt;span class="fixed"&gt;%eip&lt;/span&gt; to that value. Used to return from function  calls.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="appendix"&gt;&lt;a name="ap02"&gt;&lt;/a&gt; &lt;div class="section"&gt; &lt;h2 class="first-section-title"&gt;&lt;a name="435"&gt;&lt;/a&gt;&lt;a name="ap02lev1sec6"&gt;&lt;/a&gt;Assembler  Directives&lt;/h2&gt; &lt;p class="first-para"&gt;These are instructions to the assembler and linker, instead  of instructions to the processor. These are used to help the assembler put your  code together properly, and make it easier to use.&lt;/p&gt;&lt;a name="436"&gt;&lt;/a&gt;&lt;a name="ap02table05"&gt;&lt;/a&gt; &lt;table class="table" border="1"&gt; &lt;caption class="table-title"&gt;&lt;span class="table-title"&gt;&lt;span class="table-titlelabel"&gt;Table B-5: &lt;/span&gt;Assembler Directives&lt;/span&gt; &lt;/caption&gt; &lt;thead&gt; &lt;tr valign="top"&gt; &lt;th class="th" scope="col" align="left"&gt; &lt;p class="table-para"&gt;&lt;b class="bold"&gt;Directive&lt;/b&gt; &lt;/p&gt;&lt;/th&gt; &lt;th class="th" scope="col" align="left"&gt; &lt;p class="table-para"&gt;&lt;b class="bold"&gt;Operands&lt;/b&gt; &lt;/p&gt;&lt;/th&gt; &lt;th class="th" scope="col" align="left"&gt; &lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt; &lt;tbody&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;.ascii&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;QUOTED STRING&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" colspan="3" align="left" valign="top"&gt; &lt;p class="table-para"&gt;Takes the given quoted string and converts it into byte  data.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;.byte&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;ALLIESVALUES&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" colspan="3" align="left" valign="top"&gt; &lt;p class="table-para"&gt;Takes a comma-separated list of values and inserts them  right there in the program as data.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;.endr&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" colspan="3" align="left" valign="top"&gt; &lt;p class="table-para"&gt;Ends a repeating section defined with &lt;span class="fixed"&gt;.rept&lt;/span&gt;.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;.equ&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;LABEL, VALUE&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" colspan="3" align="left" valign="top"&gt; &lt;p class="table-para"&gt;Sets the given label equivalent to the given value. The  value can be a number, a character, or an constant expression that evaluates to  a a number or character. prom that point on, use of the label will be  substituted for the given value.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;.globl&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;LABEL&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" colspan="3" align="left" valign="top"&gt; &lt;p class="table-para"&gt;Sets the given label as global, meaning that it can be used  from separately-compiled object files.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;.include&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;FILE&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;a name="437"&gt;&lt;/a&gt;&lt;a name="IDX-267"&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" colspan="3" align="left" valign="top"&gt; &lt;p class="table-para"&gt;Includes the given file just as if it were typed in right  there.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;.lcomm&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;SYMBOL, SIZE&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" colspan="3" align="left" valign="top"&gt; &lt;p class="table-para"&gt;This is used in the &lt;span class="fixed"&gt;.bss&lt;/span&gt; section to  specify storage that should be allocated when the program is executed. Defines  the symbol with the address where the storage will be located, and makes sure  that it is the given number of bytes long.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;.long&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;VALUES&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" colspan="3" align="left" valign="top"&gt; &lt;p class="table-para"&gt;Takes a sequence of numbers separated by commas, and inserts  those numbers as 4-byte words right where they are in the program.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;.rept&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;COUNT&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" colspan="3" align="left" valign="top"&gt; &lt;p class="table-para"&gt;Repeats everything between this directive and the &lt;span class="fixed"&gt;.endr&lt;/span&gt; directives the number of times specified.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;.section&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;SECTION NAME&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" colspan="3" align="left" valign="top"&gt; &lt;p class="table-para"&gt;Switches the section that is being worked on. Common  sections include &lt;span class="fixed"&gt;.text&lt;/span&gt; (for code), &lt;span class="fixed"&gt;.data&lt;/span&gt; (for data embedded in the program itself), and &lt;span class="fixed"&gt;.bss&lt;/span&gt; (for uninitialized global data).&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;.type&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;p class="table-para"&gt;SYMBOL, @function&lt;/p&gt;&lt;/td&gt; &lt;td class="td" align="left"&gt; &lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td class="td" colspan="3" align="left" valign="top"&gt; &lt;p class="table-para"&gt;Tells the linker that the given symbol is a  function.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="section"&gt; &lt;h2 class="first-section-title"&gt;&lt;a name="438"&gt;&lt;/a&gt;&lt;a name="ap02lev1sec7"&gt;&lt;/a&gt;Differences in Other Syntaxes and Terminology&lt;/h2&gt; &lt;p class="first-para"&gt;The syntax for assembly language used in this book is known  at the &lt;i class="emphasis"&gt;AT&amp;T&lt;/i&gt; syntax. It is the one supported by the GNU  tool chain that comes standard with every Linux distribution. However, the  official syntax for x86 assembly language (known as the Intel® syntax) is  different. It is the same assembly language for the same platform, but it looks  different. Some of the differences include:&lt;/p&gt; &lt;ul class="itemizedlist"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;In Intel syntax, the operands of instructions are often  reversed. The destination operand is listed before the source operand.&lt;/p&gt;&lt;a name="439"&gt;&lt;/a&gt;&lt;a name="IDX-268"&gt;&lt;/a&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;In Intel syntax, registers are not prefixed with the percent  sign (&lt;span class="fixed"&gt;%&lt;/span&gt;).&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;In Intel syntax, a dollar-sign (&lt;span class="fixed"&gt;$&lt;/span&gt;)  is not required to do immediate-mode addressing. Instead, non-immediate  addressing is accomplished by surrounding the address with brackets (&lt;span class="fixed"&gt;[]&lt;/span&gt;).&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;In Intel syntax, the instruction name does not include the  size of data being moved. If that is ambiguous, it is explicitly stated as &lt;span class="fixed"&gt;BYTE&lt;/span&gt;, &lt;span class="fixed"&gt;WORD&lt;/span&gt;, Or &lt;span class="fixed"&gt;DWORD&lt;/span&gt; immediately after the instruction name.&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;The way that memory addresses are represented in Intel  assembly language is much different (shown below).&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;Because the x86 processor line originally started out as a  16-bit processor, most literature about x86 processors refer to words as 16-bit  values, and call 32-bit values double words. However, we use the term "word" to  refer to the standard register size on a processor, which is 32 bits on an x86  processor. The syntax also keeps this naming convention - &lt;span class="fixed"&gt;DWORD&lt;/span&gt; stands for "double word" in Intel syntax and is used  for standard-sized registers, which we would call simply a "word".&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;Intel assembly language has the ability to address memory as  a segment/offset pair. We do not mention this because Linux does not support  segmented memory, and is therefore irrelevant to normal Linux  programming.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p class="para"&gt;Other differences exist, but they are small in comparison. To show  some of the differences, consider the following instruction:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;movl %eax, 8(%ebx,%edi,4)&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;In Intel syntax, this would be written as:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;mov  [8 + %ebx + 1 * edi], eax&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="last-para"&gt;The memory reference is a bit easier to read than its  AT&amp;amp;T counterpart because it spells out exactly how the address will be  computed. However, but the order of operands in Intel syntax can be  confusing.&lt;/p&gt;&lt;div class="section"&gt; &lt;h2 class="first-section-title"&gt;&lt;a name="440"&gt;&lt;/a&gt;&lt;a name="ap02lev1sec8"&gt;&lt;/a&gt;Where to  Go for More Information&lt;/h2&gt;&lt;a name="441"&gt;&lt;/a&gt;&lt;a name="IDX-269"&gt;&lt;/a&gt; &lt;p class="para"&gt;Intel has a set of comprehensive guides to their processors. These  are available at &lt;a class="url" href="http://www.intel.com/design/pentium/manuals/" target="_top"&gt;http://www.intel.com/design/pentium/manuals/&lt;/a&gt; Note that all of  these use the Intel syntax, not the AT&amp;T syntax. The most important ones are  their &lt;i&gt;IA-32 Intel Architecture Software Developer's Manual&lt;/i&gt; in its three  volumes::&lt;/p&gt; &lt;ul class="itemizedlist"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;&lt;i&gt;Volume 1: System Programming Guide&lt;/i&gt; &lt;/p&gt; &lt;p class="last-para"&gt;(&lt;a class="url" href="http://developer.intel.com/design/pentium4/manuals/245470.htm" target="_top"&gt;http://developer.intel.com/design/pentium4/manuals/245470.htm&lt;/a&gt;)&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;&lt;i&gt;Volume 2: Instruction Set Reference&lt;/i&gt; &lt;/p&gt; &lt;p class="last-para"&gt;(&lt;a class="url" href="http://developer.intel.com/design/pentium4/manuals/245471.htm" target="_top"&gt;http://developer.intel.com/design/pentium4/manuals/245471.htm&lt;/a&gt;)&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;&lt;i&gt;Volume 3: System Programming Guide&lt;/i&gt; &lt;/p&gt; &lt;p class="last-para"&gt;(&lt;a class="url" href="http://developer.intel.com/design/pentium4/manuals/245472.htm" target="_top"&gt;http://developer.intel.com/design/pentium4/manuals/245472.htm&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p class="para"&gt;In addition, you can find a lot of information in the manual for  the GNU assembler, available online at &lt;a class="url" href="http://www.gnu.org/software/binutils/manual/gas-2.9.1/as.html" target="_top"&gt;http://www.gnu.org/software/binutils/manual/gas-2.9.1/as.html&lt;/a&gt;.  Similarly, the manual for the GNU linker is available online at &lt;a class="url" href="http://www.gnu.org/software/binutils/manual/ld-2.9.1/ld.html" target="_top"&gt;http://www.gnu.org/software/binutils/manual/ld-2.9.1/ld.html&lt;/a&gt;.&lt;/p&gt;&lt;a name="442"&gt;&lt;/a&gt;&lt;a name="IDX-270"&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8901974503278002812-7612300635539070347?l=programminggroundup.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://programminggroundup.blogspot.com/feeds/7612300635539070347/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8901974503278002812&amp;postID=7612300635539070347' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8901974503278002812/posts/default/7612300635539070347'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8901974503278002812/posts/default/7612300635539070347'/><link rel='alternate' type='text/html' href='http://programminggroundup.blogspot.com/2007/01/appendix-b-common-x86-instructions.html' title='Appendix B: Common x86 Instructions'/><author><name>Admin</name><uri>http://www.blogger.com/profile/13783659974416042562</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8901974503278002812.post-3291270304911943196</id><published>2007-01-31T19:35:00.000-08:00</published><updated>2007-01-31T19:37:33.803-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='gui programming'/><category scheme='http://www.blogger.com/atom/ns#' term='x86'/><category scheme='http://www.blogger.com/atom/ns#' term='asm'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='assembly language'/><title type='text'>Appendix A: GUI Programming</title><content type='html'>&lt;div class="section"&gt; &lt;h2 class="sect2-title"&gt;&lt;a name="394"&gt;&lt;/a&gt;&lt;a name="ap01lev1sec1"&gt;&lt;/a&gt;Introduction to  GUI Programming&lt;/h2&gt; &lt;p class="first-para"&gt;The purpose of this appendix is not to teach you how to do  Graphical User Interfaces. It is simply meant to show how writing graphical  applications is the same as writing other applications, just using an additional  library to handle the graphical parts. As a programmer you need to get used to  learning new libraries. Most of your time will be spent passing data from one  library to another.&lt;/p&gt;&lt;h2 class="first-section-title"&gt;&lt;a name="395"&gt;&lt;/a&gt;&lt;a name="ap01lev1sec2"&gt;&lt;/a&gt;The GNOME  Libraries&lt;/h2&gt; &lt;p class="first-para"&gt;The GNOME projects is one of several projects to provide a  complete desktop to Linux users. The GNOME project includes a panel to hold  application launchers and mini-applications called applets, several standard  applications to do things such as file management, session management, and  configuration, and an API for creating applications which fit in with the way  the rest of the system works.&lt;/p&gt; &lt;p class="para"&gt;One thing to notice about the GNOME libraries is that they  constantly create and give you pointers to large data structures, but you never  need to know how they are laid out in memory. All manipulation of the GUI data  structures are done entirely through function calls. This is a characteristic of  good library design. Libraries change from version to version, and so does the  data that each data structure holds. If you had to access and manipulate that  data yourself, then when the library is updated you would have to modify your  programs to work with the new library, or at least recompile them. When you  access the data through functions, the functions take care of knowing where in  the structure each piece of data is. The pointers you receive from the library  are &lt;i class="emphasis"&gt;opaque&lt;/i&gt; - you don't need to know specifically what the  structure they are pointing to looks like, you only need to know the functions  that will properly manipulate it. When designing libraries, even for use within  only one program, this is a good practice to keep in mind.&lt;/p&gt;&lt;a name="396"&gt;&lt;/a&gt;&lt;a name="IDX-240"&gt;&lt;/a&gt; &lt;p class="last-para"&gt;This chapter will not go into details about how GNOME works.  If you would like to know more, visit the GNOME developer web site at &lt;a class="url" href="http://developer.gnome.org/" target="_top"&gt;http://developer.gnome.org/&lt;/a&gt;. This site contains tutorials,  mailing lists, API documentation, and everything else you need to start  programming in the GNOME environment.&lt;/p&gt;&lt;h2 class="first-section-title"&gt;&lt;a name="397"&gt;&lt;/a&gt;&lt;a name="ap01lev1sec3"&gt;&lt;/a&gt;A Simple  GNOME Program in Several Languages&lt;/h2&gt; &lt;p class="first-para"&gt;This program will simply show a Window that has a button to  quit the application. When that button is clicked it will ask you if you are  sure, and if you click yes it will close the application. To run this program,  type in the following as&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;gnome-example.s:&lt;br /&gt;&lt;br /&gt;#PURPOSE:  This program is meant to be an example&lt;br /&gt;#          of what GUI programs look like written&lt;br /&gt;#          with the GNOME libraries&lt;br /&gt;#&lt;br /&gt;#INPUT:    The user can only click on the "Quit"&lt;br /&gt;#          button or close the window&lt;br /&gt;#&lt;br /&gt;#OUTPUT:   The application will close&lt;br /&gt;#&lt;br /&gt;#PROCESS:  If the user clicks on the "Quit" button,&lt;br /&gt;#          the program will display a dialog asking&lt;br /&gt;#          if they are sure.  If they click Yes, it&lt;br /&gt;#          will close the application.  Otherwise&lt;br /&gt;#          it will continue running&lt;br /&gt;#&lt;br /&gt;&lt;br /&gt;.section .data&lt;br /&gt;&lt;br /&gt;###GNOME definitions - These were found in the GNOME&lt;br /&gt;#                      header files for the C language&lt;br /&gt;#                      and converted into their assembly&lt;a name="398"&gt;&lt;/a&gt;&lt;a name="IDX-241"&gt;&lt;/a&gt;&lt;br /&gt;#                     equivalents&lt;br /&gt;&lt;br /&gt;#GNOME Button Names&lt;br /&gt;GNOME_STOCK_BUTTON_YES:&lt;br /&gt;.ascii "Button_Yes\0"&lt;br /&gt;GNOME_STOCK_BUTTON_NO:&lt;br /&gt;.ascii "Button_No\0"&lt;br /&gt;&lt;br /&gt;#Gnome MessageBox Types&lt;br /&gt;GNOME_MESSAGE_BOX_QUESTION:&lt;br /&gt;.ascii "question\0"&lt;br /&gt;&lt;br /&gt;#Standard definition of NULL&lt;br /&gt;.equ NULL, 0&lt;br /&gt;&lt;br /&gt;#GNOME signal definitions&lt;br /&gt;signal_destroy:&lt;br /&gt;.ascii "destroy\0"&lt;br /&gt;signal_delete_event:&lt;br /&gt;.ascii "delete_event\0"&lt;br /&gt;signal_clicked:&lt;br /&gt;.ascii "clicked\0"&lt;br /&gt;&lt;br /&gt;###Application-specific definitions&lt;br /&gt;&lt;br /&gt;#Application information&lt;br /&gt;app_id:&lt;br /&gt;.ascii "gnome-example\0"&lt;br /&gt;app_version:&lt;br /&gt;.ascii "1.000\0"&lt;br /&gt;app_title:&lt;br /&gt;.ascii "Gnome Example Program\0"&lt;br /&gt;&lt;br /&gt;#Text for Buttons and windows&lt;br /&gt;button_quit_text:&lt;a name="399"&gt;&lt;/a&gt;&lt;a name="IDX-242"&gt;&lt;/a&gt;&lt;br /&gt;.ascii "I Want to Quit the GNOME Example Program\0"&lt;br /&gt;quit_question:&lt;br /&gt;.ascii "Are you sure you want to quit?\0"&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;.section .bss&lt;br /&gt;&lt;br /&gt;#Variables to save the created widgets in&lt;br /&gt;.equ WORD_SIZE, 4&lt;br /&gt;.lcomm appPtr, WORD_SIZE&lt;br /&gt;.lcomm btnQuit, WORD_SIZE&lt;br /&gt;&lt;br /&gt;.section .text&lt;br /&gt;&lt;br /&gt;.globl main&lt;br /&gt;.type main, @function&lt;br /&gt;main:&lt;br /&gt;pushl %ebp&lt;br /&gt;movl  %esp, %ebp&lt;br /&gt;&lt;br /&gt;#Initialize GNOME libraries&lt;br /&gt;pushl 12(%ebp)     #argv&lt;br /&gt;pushl 8 (%ebp)     #argc&lt;br /&gt;pushl $app_version&lt;br /&gt;pushl $app_id&lt;br /&gt;call  gnome_init&lt;br /&gt;addl  $16, %esp    #recover the stack&lt;br /&gt;&lt;br /&gt;#Create new application window&lt;br /&gt;pushl $app_title    #Window title&lt;br /&gt;pushl $app_id       #Application ID&lt;br /&gt;call  gnome_app__new&lt;br /&gt;addl  $8, %esp      #recover the stack&lt;br /&gt;movl  %eax, appPtr  #save the window pointer&lt;a name="400"&gt;&lt;/a&gt;&lt;a name="IDX-243"&gt;&lt;/a&gt;&lt;br /&gt;#Create new button&lt;br /&gt;pushl $button_quit_text #button text&lt;br /&gt;call  gtk_button_new_with_label&lt;br /&gt;addl  $4, %esp          #recover the stack&lt;br /&gt;movl  %eax, btnQuit     #save the button pointer&lt;br /&gt;&lt;br /&gt;#Make the button show up inside the application window&lt;br /&gt;pushl btnQuit&lt;br /&gt;pushl appPtr&lt;br /&gt;call  gnome_app_set_contents&lt;br /&gt;addl  $8, %esp&lt;br /&gt;&lt;br /&gt;#Makes the button show up (only after it's window&lt;br /&gt;#shows up, though)&lt;br /&gt;pushl btnQuit&lt;br /&gt;call  gtk_widget_show&lt;br /&gt;addl  $4, %esp&lt;br /&gt;&lt;br /&gt;#Makes the application window show up&lt;br /&gt;pushl appPtr&lt;br /&gt;call  gtk_widget_show&lt;br /&gt;addl  $4, %esp&lt;br /&gt;&lt;br /&gt;#Have GNOME call our delete_handler function&lt;br /&gt;#whenever a "delete" event occurs&lt;br /&gt;pushl $NULL            #extra data to pass to our&lt;br /&gt;                      #function (we don't use any)&lt;br /&gt;pushl $delete_handler  #function address to call&lt;br /&gt;pushl $signal_delete_event #name of the signal&lt;br /&gt;pushl appPtr           #widget to listen for events on&lt;br /&gt;call  gtk_signal_connect&lt;br /&gt;addl  $16, %esp        #recover stack&lt;br /&gt;&lt;br /&gt;#Have GNOME call our destroy_handler function&lt;br /&gt;#whenever a "destroy" event occurs&lt;a name="401"&gt;&lt;/a&gt;&lt;a name="IDX-244"&gt;&lt;/a&gt;&lt;br /&gt;pushl $NULL            #extra data to pass to our&lt;br /&gt;                       #function (we don't use any)&lt;br /&gt;pushl $destroy_handler #function address to call&lt;br /&gt;pushl $signal_destroy  #name of the signal&lt;br /&gt;pushl appPtr           #widget to listen for events on&lt;br /&gt;call  gtk_signal_connect&lt;br /&gt;addl  $16, %esp        #recover stack&lt;br /&gt;&lt;br /&gt;#Have GNOME call our click_handler function&lt;br /&gt;#whenever a "click" event occurs.  Note that&lt;br /&gt;#the previous signals were listening on the&lt;br /&gt;#application window, while this one is only&lt;br /&gt;#listening on the button&lt;br /&gt;pushl $NULL&lt;br /&gt;pushl $click_handler&lt;br /&gt;pushl $signal_clicked&lt;br /&gt;pushl btnQuit&lt;br /&gt;call  gtk_signal_connect&lt;br /&gt;addl  $16, %esp&lt;br /&gt;&lt;br /&gt;#Transfer control to GNOME.  Everything that&lt;br /&gt;#happens from here out is in reaction to user&lt;br /&gt;#events, which call signal handlers.  This main&lt;br /&gt;#function just sets up the main window and connects&lt;br /&gt;#signal handlers, and the signal handlers take&lt;br /&gt;#care of the rest&lt;br /&gt;call gtk_main&lt;br /&gt;&lt;br /&gt;#After the program is finished, leave&lt;br /&gt;movl  $0, %eax&lt;br /&gt;leave&lt;br /&gt;ret&lt;br /&gt;&lt;br /&gt;#A "destroy" event happens when the widget is being&lt;br /&gt;#removed.  In this case, when the application window&lt;a name="402"&gt;&lt;/a&gt;&lt;a name="IDX-245"&gt;&lt;/a&gt;&lt;br /&gt;#is being removed, we simply want the event loop to&lt;br /&gt;#quit&lt;br /&gt;destroy_handler:&lt;br /&gt;pushl %ebp&lt;br /&gt;movl  %esp, %ebp&lt;br /&gt;&lt;br /&gt;#This causes gtk to exit it's event loop&lt;br /&gt;#as soon as it can.&lt;br /&gt;call gtk_main_quit&lt;br /&gt;&lt;br /&gt;movl $0, %eax&lt;br /&gt;leave&lt;br /&gt;ret&lt;br /&gt;&lt;br /&gt;#A "delete" event happens when the application window&lt;br /&gt;#gets clicked in the "x" that you normally use to&lt;br /&gt;#close a window&lt;br /&gt;delete_handler:&lt;br /&gt;movl  $1, %eax&lt;br /&gt;ret&lt;br /&gt;&lt;br /&gt;#A "click" event happens when the widget gets clicked&lt;br /&gt;click_handler:&lt;br /&gt;pushl %ebp&lt;br /&gt;movl  %esp, %ebp&lt;br /&gt;&lt;br /&gt;#Create the "Are you sure" dialog&lt;br /&gt;pushl $NULL                       #End of buttons&lt;br /&gt;pushl $GNOME_STOCK_BUTTON_NO      #Button 1&lt;br /&gt;pushl $GNOME_STOCK_BUTTON_YES     #Button 0&lt;br /&gt;pushl $GNOME_MESSAGE_BOX_QUESTION #Dialog type&lt;br /&gt;pushl $quit_question              #Dialog mesasge&lt;br /&gt;call  gnome_message_box_new&lt;br /&gt;addl  $16, %esp                   #recover stack&lt;a name="403"&gt;&lt;/a&gt;&lt;a name="IDX-246"&gt;&lt;/a&gt;&lt;br /&gt;#%eax now holds the pointer to the dialog window&lt;br /&gt;&lt;br /&gt;#Setting Modal to 1 prevents any other user&lt;br /&gt;#interaction while the dialog is being shown&lt;br /&gt;pushl $1&lt;br /&gt;pushl %eax&lt;br /&gt;call  gtk_window_set_modal&lt;br /&gt;popl  %eax&lt;br /&gt;addl  $4, %esp&lt;br /&gt;&lt;br /&gt;#Now we show the dialog&lt;br /&gt;pushl %eax&lt;br /&gt;call  gtk_widget_show&lt;br /&gt;popl  %eax&lt;br /&gt;&lt;br /&gt;#This sets up all the necessary signal handlers&lt;br /&gt;#in order to just show the dialog, close it when&lt;br /&gt;#one of the buttons is clicked, and return the&lt;br /&gt;#number of the button that the user clicked on.&lt;br /&gt;#The button number is based on the order the buttons&lt;br /&gt;#were pushed on in the gnome_message_box_new function&lt;br /&gt;pushl %eax&lt;br /&gt;call  gnome_dialog_run_and_close&lt;br /&gt;addl  $4, %esp&lt;br /&gt;&lt;br /&gt;#Button 0 is the Yes button.  If this is the&lt;br /&gt;#button they clicked on, tell GNOME to quit&lt;br /&gt;#it's event loop.  Otherwise, do nothing&lt;br /&gt;cmpl  $0, %eax&lt;br /&gt;jne   click_handler_end&lt;br /&gt;&lt;br /&gt;call gtk_main_quit&lt;br /&gt;&lt;br /&gt;click_handler_end:&lt;br /&gt;leave&lt;a name="404"&gt;&lt;/a&gt;&lt;a name="IDX-247"&gt;&lt;/a&gt;&lt;br /&gt;ret&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;To build this application, execute the following commands:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;as gnome-example.s -o gnome-example.o&lt;br /&gt;gcc gnome-example.o 'gnome-config --libs gnomeui' \&lt;br /&gt;   -o gnome-example&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;Then type in &lt;span class="fixed"&gt;./gnome-example&lt;/span&gt; to run  it.&lt;/p&gt; &lt;p class="para"&gt;This program, like most GUI programs, makes heavy use of passing  pointers to functions as parameters. In this program you create widgets with the  GNOME functions and then you set up functions to be called when certain events  happen. These functions are called &lt;i class="emphasis"&gt;callback&lt;/i&gt; functions. All  of the event processing is handled by the function &lt;span class="fixed"&gt;gtk_main,&lt;/span&gt; so you don't have to worry about how the events are  being processed. All you have to do is have callbacks set up to wait for  them.&lt;/p&gt; &lt;p class="para"&gt;Here is a short description of all of the GNOME functions that  were used in this program:&lt;/p&gt; &lt;p class="para"&gt;gnome_init&lt;/p&gt; &lt;ul class="simple-list"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;Takes the command-line arguments, argument count,  application id, and application version and initializes the GNOME  libraries.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p class="para"&gt;gnome_app_new&lt;/p&gt; &lt;ul class="simple-list"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;Creates a new application window, and returns a pointer to  it. Takes the application id and the window title as arguments.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p class="para"&gt;gtk_button_new_with_label&lt;/p&gt; &lt;ul class="simple-list"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;Creates a new button and returns a pointer to it. Takes one  argument - the text that is in the button.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;a name="405"&gt;&lt;/a&gt;&lt;a name="IDX-248"&gt;&lt;/a&gt; &lt;p class="para"&gt;gnome_app_set_contents&lt;/p&gt; &lt;ul class="simple-list"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;This takes a pointer to the gnome application window and  whatever widget you want (a button in this case) and makes the widget be the  contents of the application window&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p class="para"&gt;gtk_widget_show&lt;/p&gt; &lt;ul class="simple-list"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;This must be called on every widget created (application  window, buttons, text entry boxes, etc) in order for them to be visible.  However, in order for a given widget to be visible, all of its parents must be  visible as well.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p class="para"&gt;gtk_signal_connect&lt;/p&gt; &lt;ul class="simple-list"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;This is the function that connects widgets and their signal  handling callback functions. This function takes the widget pointer, the name of  the signal, the callback function, and an extra data pointer. After this  function is called, any time the given event is triggered, the callback will be  called with the widget that produced the signal and the extra data pointer. In  this application, we don't use the extra data pointer, so we just set it to  NULL, which is 0.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p class="para"&gt;gtk_main&lt;/p&gt; &lt;ul class="simple-list"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;This function causes GNOME to enter into its main loop. To  make application programming easier, GNOME handles the main loop of the program  for us. GNOME will check for events and call the appropriate callback functions  when they occur. This function will continue to process events until &lt;span class="fixed"&gt;gtk_main_quit&lt;/span&gt; is called by a signal handler.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p class="para"&gt;gtk_main_quit&lt;/p&gt; &lt;ul class="simple-list"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;This function causes GNOME to exit its main loop at the  earliest opportunity.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p class="para"&gt;gnome_message_box_new&lt;/p&gt; &lt;ul class="simple-list"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;This function creates a dialog window containing a question  and response &lt;a name="406"&gt;&lt;/a&gt;&lt;a name="IDX-249"&gt;&lt;/a&gt;buttons. It takes as parameters  the message to display, the type of message it is (warning, question, etc), and  a list of buttons to display. The final parameter should be NULL to indicate  that there are no more buttons to display.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p class="para"&gt;gtk_window_set_modal&lt;/p&gt; &lt;ul class="simple-list"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;This function makes the given window a modal window. In GUI  programming, a modal window is one that prevents event processing in other  windows until that window is closed. This is often used with Dialog  windows.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p class="para"&gt;gnome_dialog_run_and_close&lt;/p&gt; &lt;ul class="simple-list"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;This function takes a dialog pointer (the pointer returned  by &lt;span class="fixed"&gt;gnome_message_box_new&lt;/span&gt; can be used here) and will set  up all of the appropriate signal handlers so that it will run until a button is  pressed. At that time it will close the dialog and return to you which button  was pressed. The button number refers to the order in which the buttons were set  up in &lt;span class="fixed"&gt;gnome_message_box_new.&lt;/span&gt; &lt;/p&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p class="para"&gt;The following is the same program written in the C language. Type  it in as &lt;span class="fixed"&gt;gnome-example-c.c:&lt;/span&gt; &lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;/* PURPOSE:  This program is meant to be an example&lt;br /&gt;          of what GUI programs look like written&lt;br /&gt;          with the GNOME libraries&lt;br /&gt;*/&lt;br /&gt;&lt;br /&gt;#include &lt;gnome.h&gt;&lt;br /&gt;&lt;br /&gt;/* Program definitions */&lt;br /&gt;#define MY_APP_TITLE "Gnome Example Program"&lt;br /&gt;#define MY_APP_ID "gnome-example"&lt;br /&gt;#define MY_APP_VERSION "1.000"&lt;a name="407"&gt;&lt;/a&gt;&lt;a name="IDX-250"&gt;&lt;/a&gt;&lt;br /&gt;#define MY_BUTTON_TEXT "I Want to Quit the Example Program"&lt;br /&gt;#define MY_QUIT_QUESTION "Are you sure you want to quit?"&lt;br /&gt;&lt;br /&gt;/* Must declare functions before they are used */&lt;br /&gt;int destroy_handler(gpointer window,&lt;br /&gt; GdkEventAny *e,&lt;br /&gt; gpointer data);&lt;br /&gt;int delete_handler(gpointer window,&lt;br /&gt; GdkEventAny *e,&lt;br /&gt; gpointer data);&lt;br /&gt;int click__handler(gpointer window,&lt;br /&gt; GdkEventAny *e,&lt;br /&gt; gpointer data);&lt;br /&gt;&lt;br /&gt;int main(int argc, char **argv)&lt;br /&gt;{&lt;br /&gt;gpointer appPtr;  /* application window */&lt;br /&gt;gpointer btnQuit; /* quit button */&lt;br /&gt;&lt;br /&gt;/* Initialize GNOME libraries */&lt;br /&gt;gnome_init(MY_APP_ID, MY_APP_VERSION, argc, argv);&lt;br /&gt;&lt;br /&gt;/* Create new application window */&lt;br /&gt;appPtr = gnome_app_new(MY_APP_ID, MY_APP_TITLE);&lt;br /&gt;&lt;br /&gt;/* Create new button */&lt;br /&gt;btnQuit = gtk_button_new_with_label(MY_BUTTON_TEXT);&lt;br /&gt;&lt;br /&gt;/* Make the button show up inside the application window */&lt;br /&gt;gnome_app_set_contents(appPtr, btnQuit);&lt;br /&gt;&lt;br /&gt;/* Makes the button show up */&lt;br /&gt;gtk_widget_show(btnQuit);&lt;br /&gt;&lt;br /&gt;/* Makes the application window show up */&lt;a name="408"&gt;&lt;/a&gt;&lt;a name="IDX-251"&gt;&lt;/a&gt;&lt;br /&gt;gtk_widget_show(appPtr);&lt;br /&gt;&lt;br /&gt;/* Connect the signal handlers */&lt;br /&gt;gtk_signal_connect(appPtr, "delete_event",&lt;br /&gt;  GTK_SIGNAL_FUNC(delete_handler), NULL);&lt;br /&gt;gtk_signal_connect(appPtr, "destroy",&lt;br /&gt;  GTK_SIGNAL_FUNC(destroy_handler), NULL);&lt;br /&gt;gtk_signal_connect(btnQuit, "clicked",&lt;br /&gt;  GTK_SIGNAL_FUNC(click_handler), NULL);&lt;br /&gt;&lt;br /&gt;/* Transfer control to GNOME */&lt;br /&gt;gtk_main();&lt;br /&gt;&lt;br /&gt;return 0;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;/* Function to receive the "destroy" signal */&lt;br /&gt;int destroy_handler(gpointer window,&lt;br /&gt; GdkEventAny *e,&lt;br /&gt; gpointer data)&lt;br /&gt;{&lt;br /&gt;/* Leave GNOME event loop */&lt;br /&gt;gtk_main_quit();&lt;br /&gt;return 0;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;/* Function to receive the "delete_event" signal */&lt;br /&gt;int delete_handler(gpointer window,&lt;br /&gt; GdkEventAny *e,&lt;br /&gt; gpointer data)&lt;br /&gt;{&lt;br /&gt;return 0;&lt;br /&gt;}&lt;a name="409"&gt;&lt;/a&gt;&lt;a name="IDX-252"&gt;&lt;/a&gt;&lt;br /&gt;/* Function to receive the "clicked" signal */&lt;br /&gt;int click_handler(gpointer window,&lt;br /&gt; GdkEventAny *e,&lt;br /&gt; gpointer data)&lt;br /&gt;{&lt;br /&gt;gpointer msgbox;&lt;br /&gt;int buttonClicked;&lt;br /&gt;&lt;br /&gt;/* Create the "Are you sure" dialog */&lt;br /&gt;msgbox = gnome_message_box_new(&lt;br /&gt; MY_QUIT_QUESTION,&lt;br /&gt; GNOME_MESSAGE_BOX_QUESTION,&lt;br /&gt; GNOME_STOCK_BUTTON_YES,&lt;br /&gt; GNOME_STOCK_BUTTON_NO,&lt;br /&gt; NULL);&lt;br /&gt;gtk_window_set_modal(msgbox, 1);&lt;br /&gt;gtk_widget_show(msgbox);&lt;br /&gt;&lt;br /&gt;/* Run dialog box */&lt;br /&gt;buttonClicked = gnome_dialog_run_and_close(msgbox);&lt;br /&gt;&lt;br /&gt;/* Button 0 is the Yes button. If this is the&lt;br /&gt;button they clicked on, tell GNOME to quit&lt;br /&gt;it's event loop.  Otherwise, do nothing */&lt;br /&gt;if(buttonClicked == 0)&lt;br /&gt;{&lt;br /&gt; gtk_main_quit();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;return 0;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;To compile it, type&lt;/p&gt;&lt;a name="410"&gt;&lt;/a&gt;&lt;a name="IDX-253"&gt;&lt;/a&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;gcc gnome-example-c.c 'gnome-config --cflags \&lt;br /&gt;   --libs gnomeui' -o gnome-example-c&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;Run it by typing &lt;span class="fixed"&gt;./gnome-example-c.&lt;/span&gt; &lt;/p&gt; &lt;p class="para"&gt;Finally, we have a version in Python. Type it in as  gnome-example.py:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;#PURPOSE:  This program is meant to be an example&lt;br /&gt;#          of what GUI programs look like written&lt;br /&gt;#          with the GNOME libraries&lt;br /&gt;#&lt;br /&gt;&lt;br /&gt;#lmport GNOME libraries&lt;br /&gt;import gtk&lt;br /&gt;import gnome.ui&lt;br /&gt;&lt;br /&gt;####DEFINE CALLBACK FUNCTIONS FIRST####&lt;br /&gt;&lt;br /&gt;#In Python, functions have to be defined before&lt;br /&gt;#they are used, so we have to define our callback&lt;br /&gt;#functions first.&lt;br /&gt;&lt;br /&gt;def destroy_handler(event):&lt;br /&gt;gtk.mainquit()&lt;br /&gt;return 0&lt;br /&gt;&lt;br /&gt;def delete_handler(window, event):&lt;br /&gt;return 0&lt;br /&gt;&lt;br /&gt;def click_handler(event):&lt;br /&gt;#Create the "Are you sure" dialog&lt;br /&gt;msgbox = gnome.ui.GnomeMessageBox(&lt;br /&gt; "Are you sure you want to quit?",&lt;br /&gt; gnome.ui.MESSAGE_BOX_QUESTION,&lt;br /&gt; gnome.ui.STOCK_BUTTON_YES,&lt;br /&gt; gnome.ui.STOCK_BUTTON_NO)&lt;a name="411"&gt;&lt;/a&gt;&lt;a name="IDX-254"&gt;&lt;/a&gt;&lt;br /&gt;msgbox.set_modal(1)&lt;br /&gt;msgbox.show()&lt;br /&gt;&lt;br /&gt;result = msgbox.run_and_close()&lt;br /&gt;&lt;br /&gt;#Button 0 is the Yes button.  If this is the&lt;br /&gt;#button they clicked on, tell GNOME to quit&lt;br /&gt;#it's event loop.  Otherwise, do nothing&lt;br /&gt;if (result == 0):&lt;br /&gt; gtk.mainquit()&lt;br /&gt;&lt;br /&gt;return 0&lt;br /&gt;&lt;br /&gt;####MAIN PROGRAM####&lt;br /&gt;&lt;br /&gt;#Create new application window&lt;br /&gt;myapp = gnome.ui.GnomeApp(&lt;br /&gt;"gnome-example", "Gnome Example Program")&lt;br /&gt;&lt;br /&gt;#Create new button&lt;br /&gt;mybutton = gtk.GtkButton(&lt;br /&gt;"I Want to Quit the GNOME Example program")&lt;br /&gt;myapp.set_contents(mybutton)&lt;br /&gt;&lt;br /&gt;#Makes the button show up&lt;br /&gt;mybutton.show()&lt;br /&gt;&lt;br /&gt;#Makes the application window show up&lt;br /&gt;myapp.show()&lt;br /&gt;&lt;br /&gt;#Connect signal handlers&lt;br /&gt;myapp.connect("delete_event", delete_handler)&lt;br /&gt;myapp.connect("destroy", destroy_handler)&lt;br /&gt;mybutton.connect("clicked", click_handler)&lt;a name="412"&gt;&lt;/a&gt;&lt;a name="IDX-255"&gt;&lt;/a&gt;&lt;br /&gt;#Transfer control to GNOME&lt;br /&gt;gtk.mainloop()&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="last-para"&gt;To run it type &lt;span class="fixed"&gt;python gnome-example  .py.&lt;/span&gt;&lt;/p&gt;&lt;div class="section"&gt; &lt;h2 class="first-section-title"&gt;&lt;a name="413"&gt;&lt;/a&gt;&lt;a name="ap01lev1sec4"&gt;&lt;/a&gt;GUI  Builders&lt;/h2&gt; &lt;p class="first-para"&gt;In the previous example, you have created the user-interface  for the application by calling the create functions for each widget and placing  it where you wanted it. However, this can be quite burdensome for more complex  applications. Many programming environments, including GNOME, have programs  called GUI builders that can be used to automatically create your GUI for you.  You just have to write the code for the signal handlers and for initializing  your program. The main GUI builder for GNOME applications is called GLADE. GLADE  ships with most Linux distributions.&lt;/p&gt; &lt;p class="para"&gt;There are GUI builders for most programming environments. Borland  has a range of tools that will build GUIs quickly and easily on Linux and Win32  systems. The KDE environment has a tool called QT Designer which helps you  automatically develop the GUI for their system.&lt;/p&gt; &lt;p class="para"&gt;There is a broad range of choices for developing graphical  applications, but hopefully this appendix gave you a taste of what GUI  programming is like.&lt;/p&gt;&lt;a name="414"&gt;&lt;/a&gt;&lt;a name="IDX-256"&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8901974503278002812-3291270304911943196?l=programminggroundup.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://programminggroundup.blogspot.com/feeds/3291270304911943196/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8901974503278002812&amp;postID=3291270304911943196' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8901974503278002812/posts/default/3291270304911943196'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8901974503278002812/posts/default/3291270304911943196'/><link rel='alternate' type='text/html' href='http://programminggroundup.blogspot.com/2007/01/appendix-gui-programming.html' title='Appendix A: GUI Programming'/><author><name>Admin</name><uri>http://www.blogger.com/profile/13783659974416042562</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8901974503278002812.post-7833731782655715930</id><published>2007-01-31T19:29:00.000-08:00</published><updated>2007-01-31T19:32:14.109-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='x86'/><category scheme='http://www.blogger.com/atom/ns#' term='moving on'/><category scheme='http://www.blogger.com/atom/ns#' term='asm'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='assembly language'/><title type='text'>Chapter 13: Moving on From Here</title><content type='html'>&lt;div class="section"&gt; &lt;h2 class="sect2-title"&gt;&lt;a name="380"&gt;&lt;/a&gt;Overview&lt;/h2&gt;&lt;a name="381"&gt;&lt;/a&gt;&lt;a name="IDX-233"&gt;&lt;/a&gt; &lt;p class="para"&gt;Congratulations on getting this far. You should now have a basis  for understanding the issues involved in many areas of programming. Even if you  never use assembly language again, you have gained a valuable perspective and  mental framework for understanding the rest of computer science.&lt;/p&gt; &lt;p class="para"&gt;There are essentially three methods to learn to program:&lt;/p&gt; &lt;ul class="itemizedlist"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;From the Bottom Up - This is how this book teaches. It  starts with low-level programming, and works toward more generalized  teaching.&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;From the Top Down - This is the opposite direction. This  focuses on what you want to do with the computer, and teaches you how to break  it down more and more until you get to the low levels.&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;From the Middle - This is characterized by books which teach  a specific programming language or API. These are not as concerned with concepts  as they are with specifics.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p class="para"&gt;Different people like different approaches, but a good programmer  takes all of them into account. The bottom-up approaches help you understand the  machine aspects, the top-down approaches help you understand the problem-area  aspects, and the middle approaches help you with practical questions and  answers. To leave any of these aspects out would be a mistake.&lt;/p&gt; &lt;p class="para"&gt;Computer Programming is a vast subject. As a programmer, you will  need to be prepared to be constantly learning and pushing your limits. These  books will help you do that. They not only teach their subjects, but also teach  various ways and methods of &lt;i class="emphasis"&gt;thinking.&lt;/i&gt; As Alan Perlis said,  "A language that doesn't affect the way you think about programming is not worth  knowing" (&lt;a class="url" href="http://www.cs.yale.edu/homes/perlis-alan/quotes.html" target="_top"&gt;http://www.cs.yale.edu/homes/perlis-alan/quotes.html&lt;/a&gt;). If you  are constantly looking for new and better ways of doing and thinking, you will  make a successful programmer. If you do not seek to enhance yourself, "A little  sleep, a little slumber, a little folding of the hands to rest - and poverty  will come on you like a &lt;a name="382"&gt;&lt;/a&gt;&lt;a name="IDX-234"&gt;&lt;/a&gt;bandit and scarcity  like an armed man." (Proverbs 24:33-34 NIV). Perhaps not quite that severe, but  still, it is best to always be learning.&lt;/p&gt; &lt;p class="last-para"&gt;These books were selected because of their content and the  amount of respect they have in the computer science world. Each of them brings  something unique. There are many books here. The best way to start would be to  look through online reviews of several of the books, and find a starting point  that interests you.&lt;/p&gt;&lt;h2 class="first-section-title"&gt;&lt;a name="383"&gt;&lt;/a&gt;&lt;a name="ch13lev1sec1"&gt;&lt;/a&gt;From the  Bottom Up&lt;/h2&gt; &lt;p class="first-para"&gt;This list is in the best reading order I could find. It's  not necessarily easiest to hardest, but based on subject matter.&lt;/p&gt; &lt;ul class="itemizedlist"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;&lt;i&gt;&lt;a&gt;Programming from the Ground Up&lt;/a&gt;&lt;/i&gt; by Jonathan  Bartlett&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;&lt;i&gt;&lt;a&gt;Introduction to Algorithms&lt;/a&gt;&lt;/i&gt; by Thomas H.  Cormen, Charles E. Leiserson, and Ronald L. Rivest&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;&lt;i&gt;The Art of Computer Programming&lt;/i&gt; by Donald Knuth (3  volume set - volume 1 is the most important)&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;&lt;i&gt;Programming Languages&lt;/i&gt; by Samuel N. Kamin&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;&lt;i&gt;Modern Operating Systems&lt;/i&gt; by Andrew Tanenbaum&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;&lt;i&gt;Linkers and Loaders&lt;/i&gt; by John Levine&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;&lt;i&gt;Computer Organization and Design: The Hardware/Software  Interface&lt;/i&gt; by David Patterson and John Hennessy&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;div class="section"&gt; &lt;h2 class="first-section-title"&gt;&lt;a name="384"&gt;&lt;/a&gt;&lt;a name="ch13lev1sec2"&gt;&lt;/a&gt;From the  Top Down&lt;/h2&gt; &lt;p class="first-para"&gt;These books are arranged from the simplest to the hardest.  However, they can be read in any order you feel comfortable with.&lt;/p&gt;&lt;a name="385"&gt;&lt;/a&gt;&lt;a name="IDX-235"&gt;&lt;/a&gt; &lt;ul class="itemizedlist"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;&lt;i&gt;How to Design Programs&lt;/i&gt; by Matthias Felleisen, Robert  Bruce Findler, Matthew Flatt, and Shiram Krishnamurthi, available online at &lt;a class="url" href="http://www.htdp.org/" target="_top"&gt;http://www.htdp.org/&lt;/a&gt; &lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;&lt;i&gt;Simply Scheme: An Introduction to Computer Science&lt;/i&gt; by  Brian Harvey and Matthew Wright&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;&lt;i&gt;How to Think Like a Computer Scientist: Learning with  Python&lt;/i&gt; by Allen Downey, Jeff Elkner, and Chris Meyers, available online at  &lt;a class="url" href="http://www.greenteapress.com/thinkpython/" target="_top"&gt;http://www.greenteapress.com/thinkpython/&lt;/a&gt; &lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;&lt;i&gt;Structure and Interpretation of Computer Programs&lt;/i&gt; by  Harold Abelson and Gerald Jay Sussman with Julie Sussman, available online at &lt;a class="url" href="http://mitpress.mit.edu/sicp/" target="_top"&gt;http://mitpress.mit.edu/sicp/&lt;/a&gt; &lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;&lt;i&gt;Design Patterns&lt;/i&gt; by Erich Gamma, Richard Helm, Ralph  Johnson, and John Vlissides&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;&lt;i&gt;What not How: The Rules Approach to Application  Development&lt;/i&gt; by Chris Date&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;&lt;i&gt;The Algorithm Design Manual&lt;/i&gt; by Steve Skiena&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;&lt;i&gt;Programming Language Pragmatics&lt;/i&gt; by Michael Scott&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;&lt;i&gt;Essentials of Programming Languages&lt;/i&gt; by Daniel P.  Friedman, Mitchell Wand, and Christopher T. Haynes&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;div class="section"&gt; &lt;h2 class="first-section-title"&gt;&lt;a name="386"&gt;&lt;/a&gt;&lt;a name="ch13lev1sec3"&gt;&lt;/a&gt;From the  Middle Out&lt;/h2&gt; &lt;p class="first-para"&gt;Each of these is the best book on its subject. If you need  to know these languages, these will tell you all you need to know.&lt;/p&gt; &lt;ul class="itemizedlist"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;&lt;i&gt;Programming Perl&lt;/i&gt; by Larry Wall, Tom Christiansen, and  Jon Orwant&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;&lt;i&gt;Common LISP: The Language&lt;/i&gt; by Guy R. Steele&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;&lt;i&gt;ANSI Common LISP&lt;/i&gt; by Paul Graham&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;&lt;i&gt;The C Programming Language&lt;/i&gt; by Brian W. Kernighan and  Dennis M. Ritchie&lt;/p&gt;&lt;a name="387"&gt;&lt;/a&gt;&lt;a name="IDX-236"&gt;&lt;/a&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;&lt;i&gt;&lt;a&gt;The Waite Group's C Primer Plus&lt;/a&gt;&lt;/i&gt; by Stephen  Prata&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;&lt;i&gt;The C++ Programming Language&lt;/i&gt; by Bjarne Stroustrup&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;&lt;i&gt;Thinking in Java&lt;/i&gt; by Bruce Eckel, available online at  &lt;a class="url" href="http://www.mindview.net/Books/TIJ/" target="_top"&gt;http://www.mindview.net/Books/TIJ/&lt;/a&gt; &lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;&lt;i&gt;&lt;a&gt;The Scheme Programming Language&lt;/a&gt;&lt;/i&gt; by Kent  Dybvig&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;&lt;i&gt;Linux Assembly Language Programming&lt;/i&gt; by Bob  Neveln&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;div class="chapter"&gt;&lt;a name="ch13"&gt;&lt;/a&gt; &lt;div class="section"&gt; &lt;h2 class="first-section-title"&gt;&lt;a name="388"&gt;&lt;/a&gt;&lt;a name="ch13lev1sec4"&gt;&lt;/a&gt;Specialized Topics&lt;/h2&gt; &lt;p class="first-para"&gt;These books are the best books that cover their topic. They  are thorough and authoritative. To get a broad base of knowledge, you should  read several outside of the areas you normally program in.&lt;/p&gt; &lt;ul class="itemizedlist"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;Practical Programming - &lt;i&gt;Programming Pearls and More  Programming Pearls&lt;/i&gt; by Jon Louis Bentley&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;Databases - &lt;i&gt;Understanding Relational Databases&lt;/i&gt; by  Fabian Pascal&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;Project Management - &lt;i&gt;The Mythical Man-Month&lt;/i&gt; by Fred  P. Brooks&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;UNIX Programming - &lt;i&gt;The Art of UNIX Programming&lt;/i&gt; by  Eric S. Raymond, available online at &lt;a class="url" href="http://www.catb.org/%7Eesr/writings/taoup/" target="_top"&gt;http://www.catb.org/~esr/writings/taoup/&lt;/a&gt; &lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;UNIX Programming - &lt;i&gt;Advanced Programming in the UNIX  Environment&lt;/i&gt; by W. Richard Stevens&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;Network Programming - &lt;i&gt;UNIX Network Programming&lt;/i&gt; (2  volumes) by W. Richard Stevens&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;Generic Programming - &lt;i&gt;Modern C++ Design&lt;/i&gt; by Andrei  Alexandrescu&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;Compilers - &lt;i&gt;The Art of Compiler Design: Theory and  Practice&lt;/i&gt; by Thomas Pittman and James Peters&lt;/p&gt;&lt;a name="389"&gt;&lt;/a&gt;&lt;a name="IDX-237"&gt;&lt;/a&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;Compilers - &lt;i&gt;Advanced Compiler Design and  Implementation&lt;/i&gt; by Steven Muchnick&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;Development Process - &lt;i&gt;Refactoring: Improving the Design  of Existing Code&lt;/i&gt; by Martin Fowler, Kent Beck, John Brant, William Opdyke,  and Don Roberts&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;Typesetting - &lt;i&gt;Computers and Typesetting&lt;/i&gt; (5 volumes)  by Donald Knuth&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;Cryptography - &lt;i&gt;Applied Cryptography&lt;/i&gt; by Bruce  Schneier&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;Linux - &lt;i&gt;&lt;a&gt;Professional Linux Programming&lt;/a&gt;&lt;/i&gt; by Neil  Matthew, Richard Stones, and 14 other people&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;Linux Kernel - &lt;i&gt;Linux Device Drivers&lt;/i&gt; by Alessandro  Rubini and Jonathan Corbet&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;Open Source Programming - &lt;i&gt;The Cathedral and the Bazaar:  Musings on Linux and Open Source by an Accidental Revolutionary&lt;/i&gt; by Eric S.  Raymond&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;Computer Architecture - &lt;i&gt;Computer Architecture: A  Quantitative Approach&lt;/i&gt; by David Patterson and John  Hennessy&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;h2 class="first-section-title"&gt;&lt;a name="390"&gt;&lt;/a&gt;&lt;a name="ch13lev1sec5"&gt;&lt;/a&gt;Further  Resources on Assembly Language&lt;/h2&gt; &lt;p class="first-para"&gt;In assembly language, your best resources are on the  web.&lt;/p&gt; &lt;ul class="itemizedlist"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;&lt;a class="url" href="http://www.linuxassembly.org/" target="_top"&gt;http://www.linuxassembly.org/&lt;/a&gt; - a great resource for Linux  assembly language programmers&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;&lt;a class="url" href="http://www.sandpile.org/" target="_top"&gt;http://www.sandpile.org/&lt;/a&gt; - a repository of reference material on  x86, x86-64, and compatible processors&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;&lt;a class="url" href="http://www.x86.org/" target="_top"&gt;http://www.x86.org/&lt;/a&gt; - Dr. Dobb's Journal Microprocessor  Resources&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;&lt;a class="url" href="http://www.drpaulcarter.com/pcasm/" target="_top"&gt;http://www.drpaulcarter.com/pcasm/&lt;/a&gt; - Dr. Paul Carter's PC  Assembly Language Page&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;&lt;a class="url" href="http://webster.cs.ucr.edu/" target="_top"&gt;http://webster.cs.ucr.edu/&lt;/a&gt; - The Art of Assembly Home Page&lt;/p&gt;&lt;a name="391"&gt;&lt;/a&gt;&lt;a name="IDX-238"&gt;&lt;/a&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;&lt;a class="url" href="http://www.intel.com/design/pentium/manuals/" target="_top"&gt;http://www.intel.com/design/pentium/manuals/&lt;/a&gt; - Intel's manuals  for their processors&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;&lt;a class="url" href="http://www.janw.easynet.be/" target="_top"&gt;http://www.janw.easynet.be/&lt;/a&gt; - Jan Wagemaker's Linux assembly  language examples&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;&lt;a class="url" href="http://www.azillionmonkeys.com/qed/asm.html" target="_top"&gt;http://www.azillionmonkeys.com/qed/asm.html&lt;/a&gt; - Paul Hsieh's x86  Assembly Page&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8901974503278002812-7833731782655715930?l=programminggroundup.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://programminggroundup.blogspot.com/feeds/7833731782655715930/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8901974503278002812&amp;postID=7833731782655715930' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8901974503278002812/posts/default/7833731782655715930'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8901974503278002812/posts/default/7833731782655715930'/><link rel='alternate' type='text/html' href='http://programminggroundup.blogspot.com/2007/01/chapter-13-moving-on-from-here.html' title='Chapter 13: Moving on From Here'/><author><name>Admin</name><uri>http://www.blogger.com/profile/13783659974416042562</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8901974503278002812.post-97603001152222201</id><published>2007-01-31T19:26:00.000-08:00</published><updated>2007-01-31T19:29:16.261-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='x86'/><category scheme='http://www.blogger.com/atom/ns#' term='asm'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='assembly language'/><category scheme='http://www.blogger.com/atom/ns#' term='optimization'/><title type='text'>Chapter 12: Optimization</title><content type='html'>&lt;div class="highlights"&gt; &lt;p class="first-para"&gt;Optimization is the process of making your application run  more effectively. You can optimize for many things - speed, memory space usage,  disk space usage, etc. This chapter, however, focuses on speed  optimization.&lt;/p&gt;&lt;/div&gt; &lt;div class="section"&gt; &lt;h2 class="sect2-title"&gt;&lt;a name="362"&gt;&lt;/a&gt;&lt;a name="ch12lev1sec1"&gt;&lt;/a&gt;When to  Optimize&lt;/h2&gt; &lt;p class="first-para"&gt;It is better to not optimize at all than to optimize too  soon. When you optimize, your code generally becomes less clear, because it  becomes more complex. Readers of your code will have more trouble discovering  why you did what you did which will increase the cost of maintenance of your  project. Even when you know how and why your program runs the way it does,  optimized code is harder to debug and extend. It slows the development process  down considerably, both because of the time it takes to optimize the code, and  the time it takes to modify your optimized code.&lt;/p&gt; &lt;p class="para"&gt;Compounding this problem is that you don't even know beforehand  where the speed issues in your program will be. Even experienced programmers  have trouble predicting which parts of the program will be the bottlenecks which  need optimization, so you will probably end up wasting your time optimizing the  wrong parts. the Section called &lt;i class="emphasis"&gt;Where to Optimize&lt;/i&gt; will  discuss how to find the parts of your program that need optimization.&lt;/p&gt; &lt;p class="para"&gt;While you develop your program, you need to have the following  priorities:&lt;/p&gt; &lt;ul class="itemizedlist"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;Everything is documented&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;Everything works as documented&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;The code is written in an modular, easily modifiable  form&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p class="para"&gt;Documentation is essential, especially when working in groups. The  proper functioning of the program is essential. You'll notice application speed  was not &lt;a name="363"&gt;&lt;/a&gt;&lt;a name="IDX-224"&gt;&lt;/a&gt;anywhere on that list. Optimization  is not necessary during early development for the following reasons:&lt;/p&gt; &lt;ul class="itemizedlist"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;Minor speed problems can be usually solved through hardware,  which is often much cheaper than a programmer's time.&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;Your application will change dramatically as you revise it,  therefore wasting most of your efforts to optimize it. &lt;sup&gt;[&lt;a href="#ftn.N59" name="N59"&gt;1&lt;/a&gt;]&lt;/sup&gt; &lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;Speed problems are usually localized in a few places in your  code - finding these is difficult before you have most of the program  finished.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p class="para"&gt;Therefore, the time to optimize is toward the end of development,  when you have determined that your correct code actually has performance  problems.&lt;/p&gt; &lt;p class="last-para"&gt;In a web-based e-commerce project I was involved in, I  focused entirely on correctness. This was much to the dismay of my colleagues,  who were worried about the fact that each page took twelve seconds to process  before it ever started loading (most web pages process in under a second).  However, I was determined to make it the right way first, and put optimization  as a last priority. When the code was finally correct after 3 months of work, it  took only three days to find and eliminate the bottlenecks, bringing the average  processing time under a quarter of a second. By focusing on the correct order, I  was able to finish a project that was both correct and efficient.&lt;/p&gt;&lt;/div&gt; &lt;div class="footnotes"&gt; &lt;div class="footnote"&gt; &lt;p&gt;&lt;sup&gt;[&lt;a href="#N59" name="ftn.N59"&gt;1&lt;/a&gt;]&lt;/sup&gt;Many new projects often have a  first code base which is completely rewritten as developers learn more about the  problem they are trying to solve. Any optimization done on the first codebase is  completely wasted.&lt;/p&gt;&lt;h2 class="first-section-title"&gt;&lt;a name="364"&gt;&lt;/a&gt;&lt;a name="ch12lev1sec2"&gt;&lt;/a&gt;Where to  Optimize&lt;/h2&gt; &lt;p class="first-para"&gt;Once you have determined that you have a performance issue  you need to determine where in the code the problems occur. You can do this by  running a &lt;i class="emphasis"&gt;profiler.&lt;/i&gt; A profiler is a program that will let  you run your program, and it will tell you how much time is spent in each  function, and how many times they are run. &lt;a name="365"&gt;&lt;/a&gt;&lt;a name="IDX-225"&gt;&lt;/a&gt;&lt;span class="fixed"&gt;gprof&lt;/span&gt; is the standard GNU/Linux  profiling tool, but a discussion of using profilers is outside the scope of this  text. After running a profiler, you can determine which functions are called the  most or have the most time spent in them. These are the ones you should focus  your optimization efforts on.&lt;/p&gt; &lt;p class="para"&gt;If a program only spends 1 % of its time in a given function, then  no matter how much you speed it up you will only achieve a &lt;i class="emphasis"&gt;maximum&lt;/i&gt; of a 1% overall speed improvement. However, if a  program spends 20% of its time in a given function, then even minor improvements  to that functions speed will be noticeable. Therefore, profiling gives you the  information you need to make good choices about where to spend your programming  time.&lt;/p&gt; &lt;p class="para"&gt;In order to optimize functions, you need to understand in what  ways they are being called and used. The more you know about how and when a  function is called, the better position you will be in to optimize it  appropriately.&lt;/p&gt; &lt;p class="last-para"&gt;There are two main categories of optimization - local  optimizations and global optimizations. Local optimizations consist of  optimizations that are either hardware specific - such as the fastest way to  perform a given computation - or program-specific - such as making a specific  piece of code perform the best for the most often-occuring case. Global  optimization consist of optimizations which are structural. For example, if you  were trying to find the best way for three people in different cities to meet in  St. Louis, a local optimization would be finding a better road to get there,  while a global optimization would be to decide to teleconference instead of  meeting in person. Global optimization often involves restructuring code to  avoid performance problems, rather than trying to find the best way through  them.&lt;/p&gt;&lt;div class="section"&gt; &lt;h2 class="first-section-title"&gt;&lt;a name="366"&gt;&lt;/a&gt;&lt;a name="ch12lev1sec3"&gt;&lt;/a&gt;Local  Optimizations&lt;/h2&gt; &lt;p class="first-para"&gt;The following are some well-known methods of optimizing  pieces of code. When using high level languages, some of these may be done  automatically by your compiler's optimizer.&lt;/p&gt;&lt;a name="367"&gt;&lt;/a&gt;&lt;a name="IDX-226"&gt;&lt;/a&gt; &lt;p class="para"&gt;Precomputing Calculations&lt;/p&gt; &lt;ul class="simple-list"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;Sometimes a function has a limitted number of possible  inputs and outputs. In fact, it may be so few that you can actually precompute  all of the possible answers beforehand, and simply look up the answer when the  function is called. This takes up some space since you have to store all of the  answers, but for small sets of data this works out really well, especially if  the computation normally takes a long time.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p class="para"&gt;Remembering Calculation Results&lt;/p&gt; &lt;ul class="simple-list"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;This is similar to the previous method, but instead of  computing results beforehand, the result of each calculation requested is  stored. This way when the function starts, if the result has been computed  before it will simply return the previous answer, otherwise it will do the full  computation and store the result for later lookup. This has the advantage of  requiring less storage space because you aren't precomputing all results. This  is sometimes termed &lt;i class="emphasis"&gt;caching&lt;/i&gt; or &lt;i class="emphasis"&gt;memoizing.&lt;/i&gt; &lt;/p&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p class="para"&gt;Locality of Reference&lt;/p&gt; &lt;ul class="simple-list"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;&lt;i class="emphasis"&gt;Locality of reference&lt;/i&gt; is a term for  where in memory the data items you are accessing are. With virtual memory, you  may access pages of memory which are stored on disk. In such a case, the  operating system has to load that memory page from disk, and unload others to  disk. Let's say, for instance, that the operating system will allow you to have  20k of memory in physical memory and forces the rest of it to be on disk, and  your application uses 60k of memory. Let's say your program has to do 5  operations on each piece of data. If it does one operation on every piece of  data, and then goes through and does the next operation on each piece of data,  eventually every page of data will be loaded and unloaded from the disk 5 times.  Instead, if you did all 5 operations on a given data item, you only have to load  each page from disk once. When you bundle as many operations on data that is  physically close to each other in memory, then you are taking advantage of  locality of reference. &lt;a name="368"&gt;&lt;/a&gt;&lt;a name="IDX-227"&gt;&lt;/a&gt;In addition,  processors usually store some data on-chip in a cache. If you keep all of your  operations within a small area of physical memory, your program may bypass even  main memory and only use the chip's ultra-fast cache memory. This is all done  for you - all you have to do is to try to operate on small sections of memory at  a time, rather than bouncing all over the place.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p class="para"&gt;Register Usage&lt;/p&gt; &lt;ul class="simple-list"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;Registers are the fastest memory locations on the computer.  When you access memory, the processor has to wait while it is loaded from the  memory bus. However, registers are located on the processor itself, so access is  extremely fast. Therefore making wise usage of registers is extremely important.  If you have few enough data items you are working with, try to store them all in  registers. In high level languages, you do not always have this option - the  compiler decides what goes in registers and what doesn't.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p class="para"&gt;Inline Functions&lt;/p&gt; &lt;ul class="simple-list"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;Functions are great from the point of view of program  management - they make it easy to break up your program into independent,  understandable, and reuseable parts. However, function calls do involve the  overhead of pushing arguments onto the stack and doing the jumps (remember  locality of reference - your code may be swapped out on disk instead of in  memory). For high level languages, it's often impossible for compilers to do  optimizations across function-call boundaries. However, some languages support  inline functions or function macros. These functions look, smell, taste, and act  like real functions, except the compiler has the option to simply plug the code  in exactly where it was called. This makes the program faster, but it also  increases the size of the code. There are also many functions, like recursive  functions, which cannot be inlined because they call themselves either directly  or indirectly.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;a name="369"&gt;&lt;/a&gt;&lt;a name="IDX-228"&gt;&lt;/a&gt; &lt;p class="para"&gt;Optimized Instructions&lt;/p&gt; &lt;ul class="simple-list"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;Often times there are multiple assembly language  instructions which accomplish the same purpose. A skilled assembly language  programmer knows which instructions are the fastest. However, this can change  from processor to processor. For more information on this topic, you need to see  the user's manual that is provided for the specific chip you are using. As an  example, let's look at the process of loading the number 0 into a register. On  most processors, doing a &lt;span class="fixed"&gt;movl $0, %eax&lt;/span&gt; is not the  quickest way. The quickest way is to exclusive-or the register with itself,  &lt;span class="fixed"&gt;xorl %eax, %eax&lt;/span&gt;. This is because it only has to access  the register, and doesn't have to transfer any data. For users of high-level  languages, the compiler handles this kind of optimizations for you. For  assembly-language programmers, you need to know your processor  well.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p class="para"&gt;Addressing Modes&lt;/p&gt; &lt;ul class="simple-list"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;Different addressing modes work at different speeds. The  fastest are the immediate and register addressing modes. Direct is the next  fastest, indirect is next, and base pointer and indexed indirect are the  slowest. Try to use the faster addressing modes, when possible. One interesting  consequence of this is that when you have a structured piece of memory that you  are accessing using base pointer addressing, the first element can be accessed  the quickest. Since its offset is 0, you can access it using indirect addressing  instead of base pointer addressing, which makes it faster.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p class="para"&gt;Data Alignment&lt;/p&gt; &lt;ul class="simple-list"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;Some processors can access data on word-aligned memory  boundaries (i.e. - addresses divisible by the word size) faster than non-aligned  data. So, when setting up structures in memory, it is best to keep it  word-aligned. Some non-x86 processors, in fact, cannot access non-aligned data  in some modes.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p class="last-para"&gt;These are just a smattering of examples of the kinds of local  optimizations possible. However, remember that the maintainability and  readability of code is &lt;a name="370"&gt;&lt;/a&gt;&lt;a name="IDX-229"&gt;&lt;/a&gt;much more important  except under extreme circumstances.&lt;/p&gt;&lt;div class="section"&gt; &lt;h2 class="first-section-title"&gt;&lt;a name="371"&gt;&lt;/a&gt;&lt;a name="ch12lev1sec4"&gt;&lt;/a&gt;Global  Optimization&lt;/h2&gt; &lt;p class="first-para"&gt;Global optimization has two goals. The first one is to put  your code in a form where it is easy to do local optimiztions. For example, if  you have a large procedure that performs several slow, complex calculations, you  might see if you can break parts of that procedure into their own functions  where the values can be precomputed or memoized.&lt;/p&gt; &lt;p class="para"&gt;Stateless functions (functions that only operate on the parameters  that were passed to them - i.e. no globals or system calls) are the easiest type  of functions to optimize in a computer. The more stateless parts of your program  you have, the more opportunities you have to optimize. In the e-commerce  situation I wrote about above, the computer had to find all of the associated  parts for specific inventory items. This required about 12 database calls, and  in the worst case took about 20 seconds. However, the goal of this program was  to be interactive, and a long wait would destroy that goal. However, I knew that  these inventory configurations do not change. Therefore, I converted the  database calls into their own functions, which were stateless. I was then able  to memoize the functions. At the beginning of each day, the function results  were cleared in case anyone had changed them, and several inventory items were  automatically preloaded. From then on during the day, the first time someone  accessed an inventory item, it would take the 20 seconds it did beforehand, but  afterwards it would take less than a second, because the database results had  been memoized.&lt;/p&gt; &lt;p class="para"&gt;Global optimization usually often involves achieving the following  properties in your functions:&lt;/p&gt; &lt;p class="para"&gt;Parallelization&lt;/p&gt; &lt;ul class="simple-list"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;Parallelization means that your algorithm can effectively be  split among multiple processes. For example, pregnancy is not very  parallelizable because &lt;a name="372"&gt;&lt;/a&gt;&lt;a name="IDX-230"&gt;&lt;/a&gt;no matter how many  women you have, it still takes nine months. However, building a car is  parallelizable because you can have one worker working on the engine while  another one is working on the interior. Usually, applications have a limit to  how parallelizable they are. The more parallelizable your application is, the  better it can take advantage of multiprocessor and clustered computer  configurations.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p class="para"&gt;Statelessness&lt;/p&gt; &lt;ul class="simple-list"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;As we've discussed, stateless functions and programs are  those that rely entirely on the data explicitly passed to them for functioning.  Most processes are not entirely stateless, but they can be within limits. In my  e-commerce example, the function wasn't entirely stateless, but it was within  the confines of a single day. Therefore, I optimized it as if it were a  stateless function, but made allowances for changes at night. Two great benefits  resulting from statelessness is that most stateless functions are parallelizable  and often benefit from memoization.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p class="last-para"&gt;Global optimization takes quite a bit of practice to know  what works and what doesn't. Deciding how to tackle optimization problems in  code involves looking at all the issues, and knowing that fixing some issues may  cause others.&lt;/p&gt;&lt;div class="chapter"&gt;&lt;a name="ch12"&gt;&lt;/a&gt; &lt;div class="section"&gt; &lt;h2 class="first-section-title"&gt;&lt;a name="373"&gt;&lt;/a&gt;&lt;a name="ch12lev1sec5"&gt;&lt;/a&gt;Review&lt;/h2&gt; &lt;div class="section"&gt; &lt;h3 class="sect3-title"&gt;&lt;a name="374"&gt;&lt;/a&gt;&lt;a name="ch12lev2sec1"&gt;&lt;/a&gt;Know the  Concepts&lt;/h3&gt; &lt;ul class="itemizedlist"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;At what level of importance is optimization compared to the  other priorities in programming?&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;What is the difference between local and global  optimizations?&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;Name some types of local optimizations.&lt;/p&gt;&lt;a name="375"&gt;&lt;/a&gt;&lt;a name="IDX-231"&gt;&lt;/a&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;How do you determine what parts of your program need  optimization?&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;At what level of importance is optimization compared to the  other priorities in programming? Why do you think I repeated that  question?&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt; &lt;div class="section"&gt; &lt;h3 class="sect3-title"&gt;&lt;a name="376"&gt;&lt;/a&gt;&lt;a name="ch12lev2sec2"&gt;&lt;/a&gt;Use the  Concepts&lt;/h3&gt; &lt;ul class="itemizedlist"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;Go back through each program in this book and try to make  optimizations according to the procedures outlined in this chapter&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;Pick a program from the previous exercise and try to  calculate the performance impact on your code under specific inputs. &lt;sup&gt;[&lt;a href="#ftn.N54" name="N54"&gt;2&lt;/a&gt;]&lt;/sup&gt; &lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt; &lt;div class="section"&gt; &lt;h3 class="sect3-title"&gt;&lt;a name="377"&gt;&lt;/a&gt;&lt;a name="ch12lev2sec3"&gt;&lt;/a&gt;Going  Further&lt;/h3&gt; &lt;ul class="itemizedlist"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;Find an open-source program that you find particularly fast.  Contact one of the developers and ask about what kinds of optimizations they  performed to improve the speed.&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;Find an open-source program that you find particularly slow,  and try to imagine the reasons for the slowness. Then, download the code and try  to profile it using &lt;span class="fixed"&gt;gprof&lt;/span&gt; or similar tool. Find where  the code is spending the majority of the time and try to optimize it. Was the  reason for the slowness different than you imagined?&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;Has the compiler eliminated the need for local  optimizations? Why or why not?&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;What kind of problems might a compiler run in to if it tried  to optimize code across function call boundaries?&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;a name="378"&gt;&lt;/a&gt;&lt;a name="IDX-232"&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt; &lt;div class="footnotes"&gt; &lt;div class="footnote"&gt; &lt;p&gt;&lt;sup&gt;[&lt;a href="#N54" name="ftn.N54"&gt;2&lt;/a&gt;]&lt;/sup&gt;Since these programs are  usually short enough not to have noticeable performance problems, looping  through the program thousands of times will exaggerate the time it takes to run  enough to make calculations.&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8901974503278002812-97603001152222201?l=programminggroundup.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://programminggroundup.blogspot.com/feeds/97603001152222201/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8901974503278002812&amp;postID=97603001152222201' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8901974503278002812/posts/default/97603001152222201'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8901974503278002812/posts/default/97603001152222201'/><link rel='alternate' type='text/html' href='http://programminggroundup.blogspot.com/2007/01/chapter-12-optimization.html' title='Chapter 12: Optimization'/><author><name>Admin</name><uri>http://www.blogger.com/profile/13783659974416042562</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8901974503278002812.post-8236878061672351984</id><published>2007-01-31T19:22:00.000-08:00</published><updated>2007-01-31T20:25:58.512-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='x86'/><category scheme='http://www.blogger.com/atom/ns#' term='high-level languages'/><category scheme='http://www.blogger.com/atom/ns#' term='asm'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='assembly language'/><title type='text'>Chapter 11: High-Level Languages</title><content type='html'>&lt;h2 class="sect2-title"&gt;&lt;a name="341"&gt;&lt;/a&gt;Overview&lt;/h2&gt;&lt;a name="342"&gt;&lt;/a&gt;&lt;a name="IDX-213"&gt;&lt;/a&gt; &lt;div class="highlights"&gt; &lt;p class="first-para"&gt;In this chapter we will begin to look at our first  "real-world" programming language. Assembly language is the language used at the  machine's level, but most people find coding in assembly language too cumbersome  for everyday use. Many computer languages have been invented to make the  programming task easier. Knowing a wide variety of languages is useful for many  reasons, including&lt;/p&gt; &lt;ul class="itemizedlist"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;Different languages are based on different concepts, which  will help you to learn different and better programming methods and ideas.&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;Different languages are good for different types of  projects.&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;Different companies have different standard languages, so  knowing more languages makes your skills more marketable.&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;The more languages you know, the easier it is to pick up new  ones.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p class="last-para"&gt;As a programmer, you will often have to pick up new  languages. Professional programmers can usually pick up a new language with  about a weeks worth of study and practice. Languages are simply tools, and  learning to use a new tool should not be something a programmer flinches at. In  fact, if you do computer consulting you will often have to learn new languages  on the spot in order to keep yourself employed. It will often be your customer,  not you, who decides what language is used. This chapter will introduce you to a  few of the languages available to you. I encourage you to explore as many  languages as you are interested in. I personally try to learn a new language  every few months.&lt;/p&gt;&lt;div class="section"&gt; &lt;h2 class="first-section-title"&gt;&lt;a name="343"&gt;&lt;/a&gt;&lt;a name="ch11lev1sec1"&gt;&lt;/a&gt;Compiled  and Interpreted Languages&lt;/h2&gt; &lt;p class="first-para"&gt;Many languages are &lt;i class="emphasis"&gt;compiled&lt;/i&gt; languages.  When you write assembly language, each instruction you write is translated into  exactly one machine instruction for processing. With compilers, a statement can  translate into one or hundreds of &lt;a name="344"&gt;&lt;/a&gt;&lt;a name="IDX-214"&gt;&lt;/a&gt;machine  instructions. In fact, depending on how advanced your compiler is, it might even  restructure parts of your code to make it faster. In assembly language what you  write is what you get.&lt;/p&gt; &lt;p class="para"&gt;There are also languages that are &lt;i class="emphasis"&gt;interpreted&lt;/i&gt; languages. These languages require that the user  run a program called an &lt;i class="emphasis"&gt;interpreter&lt;/i&gt; that in turn runs the  given program. These are usually slower than compiled programs, since the  interpreter has to read and interpret the code as it goes along. However, in  well-made interpreters, this time can be fairly negligible. There is also a  class of hybrid languages which partially compile a program before execution  into byte-codes. This is done because the interpreter can read the byte-codes  much faster than it can read the regular language.&lt;/p&gt; &lt;p class="para"&gt;There are many reasons to choose one or the other. Compiled  programs are nice, because you don't have to already have an interpreter  installed in the user's machine. You have to have a compiler for the language,  but the users of your program don't. In an interpreted language, you have to be  sure that the user has an interpreter installed for your program, and that the  computer knows which interpreter to run your program with. However, interpeted  languages tend to be more flexible, while compiled languages are more rigid.&lt;/p&gt; &lt;p class="para"&gt;Language choice is usually driven by available tools and support  for programming methods rather than by whether a language is compiled or  interpretted. In fact many languages have options for either one.&lt;/p&gt; &lt;p class="para"&gt;High-level languages, whether compiled or interpreted, are  oriented around you, the programmer, instead of around the machine. This opens  them up to a wide variety of features, which can include the following:&lt;/p&gt; &lt;ul class="itemizedlist"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;Being able to group multiple operations into a single  expression&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;Being able to use "big values" - values that are much more  conceptual than the 4-byte words that computers normally deal with (for example,  being able to view text strings as a single value rather than as a string of  bytes).&lt;/p&gt;&lt;a name="345"&gt;&lt;/a&gt;&lt;a name="IDX-215"&gt;&lt;/a&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;Having access to better flow control constructs than just  jumps.&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;Having a compiler to check types of value assignments and  other assertions.&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;Having memory handled automatically.&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;Being able to work in a language that resembles the problem  domain rather than the computer hardware.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p class="para"&gt;So why does one choose one language over another? For example,  many choose Perl because it has a vast library of functions for handling just  about every protocol or type of data on the planet. Python, however, has a  cleaner syntax and often lends itself to more straightforward solutions. Its  cross-platform GUI tools are also excellent. PHP makes writing web applications  simple. Common LISP has more power and features than any other environment for  those willing to learn it. Scheme is the model of simplicity and power combined  together. C is easy to interface with other languages.&lt;/p&gt; &lt;p class="last-para"&gt;Each language is different, and the more languages you know  the better programmer you will be. Knowing the concepts of different languages  will help you in all programming, because you can match the programming language  to the problem better, and you have a larger set of tools to work with. Even if  certain features aren't directly supported in the language you are using, often  they can be simulated. However, if you don't have a broad experience with  languages, you won't know of all the possibilities you have to choose  from.&lt;/p&gt;&lt;h2 class="first-section-title"&gt;&lt;a name="346"&gt;&lt;/a&gt;&lt;a name="ch11lev1sec2"&gt;&lt;/a&gt;Your  First C Program&lt;/h2&gt; &lt;p class="first-para"&gt;Here is your first C program, which prints "Hello world" to  the screen and exits. Type it in, and give it the name Hello-World.c&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;#include &lt;stdio.h&gt;&lt;br /&gt;&lt;br /&gt;/* PURPOSE:  This program is mean to show a basic */&lt;br /&gt;/*           C program.  All it does is print     */&lt;a name="347"&gt;&lt;/a&gt;&lt;a name="IDX-216"&gt;&lt;/a&gt;&lt;br /&gt;/*           "Hello World!" to the screen and     */&lt;br /&gt;/*           exit.                                */&lt;br /&gt;&lt;br /&gt;/* Main Program */&lt;br /&gt;int main(int argc, char **argv)&lt;br /&gt;{&lt;br /&gt;/* Print our string to standard output */&lt;br /&gt;puts("Hello World!\n");&lt;br /&gt;&lt;br /&gt;/* Exit with status 0 */&lt;br /&gt;return 0;&lt;br /&gt;}&lt;br /&gt;&lt;/stdio.h&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;As you can see, it's a pretty simple program. To compile it, run  the command&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;gcc -o HelloWorld Hello-World.c&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;To run the program, do&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;./HelloWorld&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;Let's look at how this program was put together.&lt;/p&gt; &lt;p class="para"&gt;Comments in C are started with &lt;span class="fixed"&gt;/*&lt;/span&gt; and  ended with &lt;span class="fixed"&gt;*/&lt;/span&gt;. Comments can span multiple lines, but  many people prefer to start and end comments on the same line so they don't get  confused.&lt;/p&gt; &lt;p class="para"&gt;&lt;span class="fixed"&gt;#include &lt;stdio.h&gt;&lt;/stdio.h&gt;&lt;/span&gt; is the first  part of the program. This is a &lt;i class="emphasis"&gt;preprocessor directive.&lt;/i&gt; C  compiling is split into two stages - the preprocessor and the main compiler.  This directive tells the preprocessor to look for the file &lt;span class="fixed"&gt;stdio.h&lt;/span&gt; and paste it into your program. The preprocessor is  responsible for putting together the text of the program. This includes sticking  different files together, running macros on your program text, etc. After the  text is put together, the preprocessor is done and the main compiler goes to  work.&lt;/p&gt;&lt;a name="348"&gt;&lt;/a&gt;&lt;a name="IDX-217"&gt;&lt;/a&gt; &lt;p class="para"&gt;Now, everything in &lt;span class="fixed"&gt;stdio.h&lt;/span&gt; is now in your  program just as if you typed it there yourself. The angle brackets around the  filename tell the compiler to look in its standard paths for the file (&lt;span class="fixed"&gt;/usr/include&lt;/span&gt; and &lt;span class="fixed"&gt;/usr/local/include&lt;/span&gt;,  usually). If it was in quotes, like &lt;span class="fixed"&gt;#include "stdio.h"&lt;/span&gt;  it would look in the current directory for the file. Anyway, &lt;span class="fixed"&gt;stdio.h&lt;/span&gt; contains the declarations for the standard input and  output functions and variables. These declarations tell the compiler what  functions are available for input and output. The next few lines are simply  comments about the program.&lt;/p&gt; &lt;p class="para"&gt;Then there is the line &lt;span class="fixed"&gt;int main (int argc, char  **argv)&lt;/span&gt;. This is the start of a function. C Functions are declared with  their name, arguments and return type. This declaration says that the function's  name is &lt;span class="fixed"&gt;main&lt;/span&gt;, it returns an &lt;span class="fixed"&gt;int&lt;/span&gt; (integer - 4 bytes long on the x86 platform), and has two  arguments - an &lt;span class="fixed"&gt;int&lt;/span&gt; called &lt;span class="fixed"&gt;argc&lt;/span&gt;  and a &lt;span class="fixed"&gt;char&lt;/span&gt; &lt;span class="fixed"&gt;**&lt;/span&gt; called &lt;span class="fixed"&gt;argv&lt;/span&gt;. You don't have to worry about where the arguments are  positioned on the stack - the C compiler takes care of that for you. You also  don't have to worry about loading values into and out of registers because the  compiler takes care of that, too.&lt;/p&gt; &lt;p class="para"&gt;The &lt;span class="fixed"&gt;main&lt;/span&gt; function is a special function  in the C language - it is the start of all C programs (much like &lt;span class="fixed"&gt;_start&lt;/span&gt; in our assembly-language programs). It always takes  two parameters. The first parameter is the number of arguments given to this  command, and the second parameter is a list of the arguments that were  given.&lt;/p&gt; &lt;p class="para"&gt;The next line is a function call. In assembly language, you had to  push the arguments of a function onto the stack, and then call the function. C  takes care of this complexity for you. You simply have to call the function with  the parameters in parenthesis. In this case, we call the function &lt;span class="fixed"&gt;puts&lt;/span&gt;, with a single parameter. This parameter is the  character string we want to print. We just have to type in the string in  quotations, and the compiler takes care of defining storage and moving the  pointers to that storage onto the stack before calling the function. As you can  see, it's a lot less work.&lt;/p&gt; &lt;p class="para"&gt;Finally our function returns the number &lt;span class="fixed"&gt;0&lt;/span&gt;. In assembly language, we stored our return value in &lt;span class="fixed"&gt;%eax&lt;/span&gt;, but in C we just use the &lt;span class="fixed"&gt;return&lt;/span&gt; command and it takes care &lt;a name="349"&gt;&lt;/a&gt;&lt;a name="IDX-218"&gt;&lt;/a&gt;of that for us. The return value of the &lt;span class="fixed"&gt;main&lt;/span&gt; function is what is used as the exit code for the  program.&lt;/p&gt; &lt;p class="para"&gt;As you can see, using high-level languages makes life much easier.  It also allows our programs to run on multiple platforms more easily. In  assembly language, your program is tied to both the operating system and the  hardware platform, while in compiled and interpreted languages the same code can  usually run on multiple operating systems and hardware platforms. For example,  this program can be built and executed on x86 hardware running Linux®, Windows®,  UNIX®, or most other operating systems. In addition, it can also run on  Macintosh hardware running a number of operating systems.&lt;/p&gt; &lt;p class="last-para"&gt;Additional information on the C programming language can be  found in &lt;span class="chapterjump"&gt;Appendix  E&lt;/span&gt;.&lt;/p&gt;&lt;div class="chapter"&gt;&lt;a name="ch11"&gt;&lt;/a&gt; &lt;div class="section"&gt; &lt;h2 class="first-section-title"&gt;&lt;a name="350"&gt;&lt;/a&gt;&lt;a name="ch11lev1sec3"&gt;&lt;/a&gt;Perl&lt;/h2&gt; &lt;p class="first-para"&gt;Perl is an interpreted language, existing mostly on Linux  and UNIX-based platforms. It actually runs on almost all platforms, but you find  it most often on Linux and UNIX-based ones. Anyway, here is the Perl version of  the program, which should be typed into a file named &lt;span class="fixed"&gt;Hello-World.pl&lt;/span&gt;:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;#!/usr/bin/perl&lt;br /&gt;&lt;br /&gt;print("Hello world!\n");&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;Since Perl is interpreted, you don't need to compile or link it.  Just run in with the following command:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;perl Hello-World.pl&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;As you can see, the Perl version is even shorter than the C  version. With Perl you don't have to declare any functions or program entry  points. You can just start &lt;a name="351"&gt;&lt;/a&gt;&lt;a name="IDX-219"&gt;&lt;/a&gt;typing commands  and the interpreter will run them as it comes to them. In fact this program only  has two lines of code, one of which is optional.&lt;/p&gt; &lt;p class="para"&gt;The first, optional line is used for UNIX machines to tell which  interpreter to use to run the program. The &lt;span class="fixed"&gt;#!&lt;/span&gt; tells the  computer that this is an interpreted program, and the &lt;span class="fixed"&gt;/usr/bin/perl&lt;/span&gt; tells the computer to use the program &lt;span class="fixed"&gt;/usr/bin/perl&lt;/span&gt; to interpret the program. However, since we ran  the program by typing in &lt;span class="fixed"&gt;perl Hello-World.pl&lt;/span&gt;, we had  already specified that we were using the perl interpreter.&lt;/p&gt; &lt;p class="para"&gt;The next line calls a Perl builtin function, print. This has one  parameter, the string to print. The program doesn't have an explicit return  statement - it knows to return simply because it runs off the end of the file.  It also knows to return 0 because there were no errors while it ran. You can see  that interpreted languages are often focused on letting you get working code as  quickly as possible, without having to do a lot of extra legwork.&lt;/p&gt; &lt;p class="last-para"&gt;One thing about Perl that isn't so evident from this example  is that Perl treats strings as a single value. In assembly language, we had to  program according to the computer's memory architecture, which meant that  strings had to be treated as a sequence of multiple values, with a pointer to  the first letter. Perl pretends that strings can be stored directly as values,  and thus hides the complication of manipulating them for you. In fact, one of  Perl's main strengths is its ability and speed at manipulating  text.&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;h2 class="first-section-title"&gt;&lt;a name="352"&gt;&lt;/a&gt;&lt;a name="ch11lev1sec4"&gt;&lt;/a&gt;Python&lt;/h2&gt; &lt;p class="first-para"&gt;The Python version of the program looks almost exactly like  the Perl one. However, Python is really a very different language than Perl,  even if it doesn't seem so from this trivial example. Type the program into a  file named &lt;span class="fixed"&gt;Hello-World.py&lt;/span&gt;. The program follows:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;#!/usr/bin/python&lt;a name="353"&gt;&lt;/a&gt;&lt;a name="IDX-220"&gt;&lt;/a&gt;&lt;br /&gt;print "Hello World"&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="last-para"&gt;You should be able to tell what the different lines of the  program do.&lt;/p&gt;&lt;div class="section"&gt; &lt;h2 class="first-section-title"&gt;&lt;a name="354"&gt;&lt;/a&gt;&lt;a name="ch11lev1sec5"&gt;&lt;/a&gt;Review&lt;/h2&gt; &lt;div class="section"&gt; &lt;h3 class="sect3-title"&gt;&lt;a name="355"&gt;&lt;/a&gt;&lt;a name="ch11lev2sec1"&gt;&lt;/a&gt;Know the  Concepts&lt;/h3&gt; &lt;ul class="itemizedlist"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;What is the difference between an intepretted language and a  compiled language?&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;What reasons might cause you to need to learn a new  programming language?&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt; &lt;div class="section"&gt; &lt;h3 class="sect3-title"&gt;&lt;a name="356"&gt;&lt;/a&gt;&lt;a name="ch11lev2sec2"&gt;&lt;/a&gt;Use the  Concepts&lt;/h3&gt; &lt;ul class="itemizedlist"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;Learn the basic syntax of a new programming language.  Re-code one of the programs in this book in that language.&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;In the program you wrote in the question above, what  specific things were automated in the programming language you chose?&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;Modify your program so that it runs 10,000 times in a row,  both in assembly language and in your new language. Then run the &lt;span class="fixed"&gt;time&lt;/span&gt; command to see which is faster. Which does come out  ahead? Why do you think that is?&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;How does the programming language's input/output methods  differ from that of the Linux system calls?&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;a name="357"&gt;&lt;/a&gt;&lt;a name="IDX-221"&gt;&lt;/a&gt;&lt;/div&gt; &lt;div class="section"&gt; &lt;h3 class="sect3-title"&gt;&lt;a name="358"&gt;&lt;/a&gt;&lt;a name="ch11lev2sec3"&gt;&lt;/a&gt;Going  Further&lt;/h3&gt; &lt;ul class="itemizedlist"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;Having seen languages which have such brevity as Perl, why  do you think this book started you with a language as verbose as assembly  language?&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;How do you think high level languages have affected the  process of programming?&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;Why do you think so many languages exist?&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;Learn two new high level languages. How do they differ from  each other? How are they similar? What approach to problem-solving does each  take?&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;a name="359"&gt;&lt;/a&gt;&lt;a name="IDX-222"&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8901974503278002812-8236878061672351984?l=programminggroundup.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://programminggroundup.blogspot.com/feeds/8236878061672351984/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8901974503278002812&amp;postID=8236878061672351984' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8901974503278002812/posts/default/8236878061672351984'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8901974503278002812/posts/default/8236878061672351984'/><link rel='alternate' type='text/html' href='http://programminggroundup.blogspot.com/2007/01/chapter-11-high-level-languages.html' title='Chapter 11: High-Level Languages'/><author><name>Admin</name><uri>http://www.blogger.com/profile/13783659974416042562</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8901974503278002812.post-7379902394750515448</id><published>2007-01-31T18:40:00.000-08:00</published><updated>2008-12-08T14:18:10.193-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='x86'/><category scheme='http://www.blogger.com/atom/ns#' term='asm'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='assembly language'/><category scheme='http://www.blogger.com/atom/ns#' term='counting'/><title type='text'>Chapter 10: Counting like a Computer</title><content type='html'>&lt;a name="291"&gt;&lt;/a&gt;&lt;a name="ch10lev1sec1"&gt;&lt;/a&gt;  &lt;div class="section"&gt; &lt;h3 class="sect3-title"&gt;&lt;a name="292"&gt;&lt;/a&gt;&lt;a name="ch10lev2sec1"&gt;&lt;/a&gt;&lt;/h3&gt;&lt;h2 class="sect2-title"&gt;&lt;a name="291"&gt;&lt;/a&gt;&lt;a name="ch10lev1sec1"&gt;&lt;/a&gt;Counting&lt;/h2&gt; &lt;div class="section"&gt; &lt;h3 class="sect3-title"&gt;&lt;a name="292"&gt;&lt;/a&gt;&lt;a name="ch10lev2sec1"&gt;&lt;/a&gt;Counting like a  Human&lt;/h3&gt;&lt;/div&gt; &lt;p class="first-para"&gt;In many ways, computers count just like humans. So, before  we start learning how computers count, let's take a deeper look at how we  count.&lt;/p&gt; &lt;p class="para"&gt;How many fingers do you have? No, it's not a trick question.  Humans (normally) have ten fingers. Why is that significant? Look at our  numbering system. At what point does a one-digit number become a two-digit  number? That's right, at ten. Humans count and do math using a base ten  numbering system. Base ten means that we group everything in tens. Let's say  we're counting sheep. 1, 2, 3, 4, 5, 6, 7, 8, 9, 10. Why did we all of a sudden  now have two digits, and re-use the 1 ? That's because we're grouping our  numbers by ten, and we have 1 group of ten sheep. Okay, let's go to the next  number 11. That means we have 1 group of ten sheep, and 1 sheep left ungrouped.  So we continue - 12, 13, 14, 15, 16, 17, 18, 19, 20. Now we have 2 groups of  ten. 21 - 2 groups of ten, and 1 sheep ungrouped. 22 - 2 groups of ten, and 2  sheep ungrouped. So, let's say we keep counting, and get to 97, 98, 99, and 100.  Look, it happened again! What happens at 100? We now have ten groups of ten. At  101 we have ten groups of ten, and 1 ungrouped sheep. So we can look at any  number like this. If we counted 60879 sheep, that would mean that we had 6  groups of ten groups of ten groups of ten groups of ten, 0 groups of ten groups  of ten groups of ten, 8 groups of ten groups of ten, 7 groups of ten, and 9  sheep left ungrouped.&lt;/p&gt; &lt;p class="last-para"&gt;So, is there anything significant about grouping things by  ten? No! It's just that grouping by ten is how we've always done it, because we  have ten fingers. We could have grouped at nine or at eleven (in which case we  would have had to make up a new symbol). The only difference between the  different groupings of numbers is that we have to re-learn our multiplication,  addition, subtraction, and &lt;a name="293"&gt;&lt;/a&gt;&lt;a name="IDX-182"&gt;&lt;/a&gt;division tables  for each grouping. The rules haven't changed, just the way we represent them.  Also, some of our tricks that we learned don't always apply, either. For  example, let's say we grouped by nine instead of ten. Moving the decimal point  one digit to the right no longer multiplies by ten, it now multiplies by nine.  In base nine, 500 is only nine times as large as 50.&lt;/p&gt;&lt;/div&gt; &lt;div class="section"&gt; &lt;h3 class="sect3-title"&gt;&lt;a name="294"&gt;&lt;/a&gt;&lt;a name="ch10lev2sec2"&gt;&lt;/a&gt;Counting like a  Computer&lt;/h3&gt; &lt;p class="first-para"&gt;The question is, how many fingers does the computer have to  count with? The computer only has two fingers. So that means all of the groups  are groups of two. So, let's count in binary - 0 (zero), 1 (one), 10 (two - one  group of two), 11 (three - one group of two and one left over), 100 (four - two  groups of two), 101 (five - two groups of two and one left over), 110 (six - two  groups of two and one group of two), and so on. In base two, moving the decimal  one digit to the right multiplies by two, and moving it to the left divides by  two. Base two is also referred to as binary.&lt;/p&gt; &lt;p class="para"&gt;The nice thing about base two is that the basic math tables are  very short. In base ten, the multiplication tables are ten columns wide, and ten  columns tall. In base two, it is very simple:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;Table of binary addition&lt;br /&gt;&lt;br /&gt;+ |  0  |  1&lt;br /&gt;--+-----+-----&lt;br /&gt;0 |  0  |  0&lt;br /&gt;--+-----+-----&lt;br /&gt;1 |  1  | 10&lt;br /&gt;&lt;br /&gt;Table of binary multiplication&lt;a name="295"&gt;&lt;/a&gt;&lt;a name="IDX-183"&gt;&lt;/a&gt;&lt;br /&gt;* |  0  |  1&lt;br /&gt;--+-----+-----&lt;br /&gt;0 |  0  |  0&lt;br /&gt;--+-----+-----&lt;br /&gt;1 |  0  |  1&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;So, let's add the numbers 10010101 with 1100101:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;   10010101&lt;br /&gt;+   1100101&lt;br /&gt;-----------&lt;br /&gt;11111010&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;Now, let's multiply them:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;        10010101&lt;br /&gt;*   1100101&lt;br /&gt;-----------&lt;br /&gt;   10010101&lt;br /&gt;  00000000&lt;br /&gt; 10010101&lt;br /&gt;00000000&lt;br /&gt;00000000&lt;br /&gt;10010101&lt;br /&gt;10010101&lt;br /&gt;---------------&lt;br /&gt;11101011001001&lt;br /&gt;&lt;a name="296"&gt;&lt;/a&gt;&lt;a name="IDX-184"&gt;&lt;/a&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt; &lt;div class="section"&gt; &lt;h3 class="sect3-title"&gt;&lt;a name="297"&gt;&lt;/a&gt;&lt;a name="ch10lev2sec3"&gt;&lt;/a&gt;Conversions  between Binary and Decimal&lt;/h3&gt; &lt;p class="first-para"&gt;Let's learn how to convert numbers from binary (base two) to  decimal (base ten). This is actually a rather simple process. If you remember,  each digit stands for some grouping of two. So, we just need to add up what each  digit represents, and we will have a decimal number. Take the binary number  10010101. To find out what it is in decimal, we take it apart like this:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;     1    0    0    1    0    1    0    1&lt;br /&gt;|    |    |    |    |    |    |    |&lt;br /&gt;|    |    |    |    |    |    |    Individual units (2^0)&lt;br /&gt;|    |    |    |    |    |    0 groups of 2 (2^1)&lt;br /&gt;|    |    |    |    |    1 group of 4 (2^2)&lt;br /&gt;|    |    |    |    0 groups of 8 (2^3)&lt;br /&gt;|    |    |    1 group of 16 (2^4)&lt;br /&gt;|    |    0 groups of 32 (2^5)&lt;br /&gt;|    0 groups of 64 (2^6)&lt;br /&gt;1 group of 128 (2^7)&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;and then we add all of the pieces together, like this:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;1*128 + 0*64 + 0*32 + 1*16 + 0*8 + 1*4 + 0*2 + 1*1 =&lt;br /&gt;128 + 16 + 4 + 1 =&lt;br /&gt;149&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;So 10010101 in binary is 149 in decimal. Let's look at 1100101. It  can be written as&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;1*64 + 1*32 + 0 * 16 + 0*8 + 1*4 + 0*2 + 1*1 =&lt;br /&gt;64 + 32 + 4 + 1 =&lt;br /&gt;101&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;So we see that 1100101 in binary is 101 in decimal. Let's look at  one more number, 11101011001001. You can convert it to decimal by doing&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;1*8192 + 1*4096 + 1*2048 + 0*1024 + 1*512 + 0*256&lt;a name="298"&gt;&lt;/a&gt;&lt;a name="IDX-185"&gt;&lt;/a&gt;&lt;br /&gt;  + 1*128 + 1*64 + 0*32 + 0*16 + 1*8 + 0*4&lt;br /&gt;  + 0*2 + 1*1 =&lt;br /&gt;&lt;br /&gt;8192 + 4096 + 2048 + 512 + 128 + 64 + 8 + 1 =&lt;br /&gt;&lt;br /&gt;15049&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;Now, if you've been paying attention, you have noticed that the  numbers we just converted are the same ones we used to multiply with earlier.  So, let's check our results: 101 * 149 = 15049. It worked!&lt;/p&gt; &lt;p class="para"&gt;Now let's look at going from decimal back to binary. In order to  do the conversion, you have to &lt;i class="emphasis"&gt;divide&lt;/i&gt; the number into  groups of two. So, let's say you had the number 17. If you divide it by two, you  get 8 with 1 left over. So that means there are 8 groups of two, and 1  ungrouped. That means that the rightmost digit will be 1. Now, we have the  rigtmost digit figured out, and 8 groups of 2 left over. Now, let's see how many  groups of two groups of two we have, by dividing 8 by 2. We get 4, with nothing  left over. That means that all groups two can be further divided into more  groups of two. So, we have 0 groups of only two. So the next digit to the left  is 0. So, we divide 4 by 2 and get two, with 0 left over, so the next digit is  0. Then, we divide 2 by 2 and get 1, with 0 left over. So the next digit is 0.  Finally, we divide 1 by 2 and get 0 with 1 left over, so the next digit to the  left is 1. Now, there's nothing left, so we're done. So, the number we wound up  with is 10001.&lt;/p&gt; &lt;p class="para"&gt;Previously, we converted to binary 11101011001001 to decimal  15049. Let's do the reverse to make sure that we did it right:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;15049 / 2 = 7524    Remaining 1&lt;br /&gt;7524 / 2 = 3762     Remaining 0&lt;br /&gt;3762 / 2 = 1881     Remaining 0&lt;br /&gt;1881 / 2 = 940      Remaining 1&lt;br /&gt;940 / 2 = 470       Remaining 0&lt;br /&gt;470 / 2 = 235       Remaining 0&lt;br /&gt;235 / 2 = 117       Remaining 1&lt;br /&gt;117 / 2 = 58        Remaining 1&lt;a name="299"&gt;&lt;/a&gt;&lt;a name="IDX-186"&gt;&lt;/a&gt;&lt;br /&gt;58 / 2 = 29         Remaining 0&lt;br /&gt;29 / 2 = 14         Remaining 1&lt;br /&gt;14 / 2 = 7          Remaining 0&lt;br /&gt;7 / 2 = 3           Remaining 1&lt;br /&gt;3 / 2 = 1           Remaining 1&lt;br /&gt;1 / 2 = 0           Remaining 1&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;Then, we put the remaining numbers back together, and we have the  original number! Remember the first division remainder goes to the far right, so  from the bottom up you have 11101011001001.&lt;/p&gt; &lt;p class="para"&gt;Each digit in a binary number is called a &lt;i class="emphasis"&gt;bit,&lt;/i&gt; which stands for &lt;i class="emphasis"&gt;binary digit.&lt;/i&gt;  Remember, computers divide up their memory into storage locations called bytes.  Each storage location on an x86 processor (and most others) is 8 bits long.  Earlier we said that a byte can hold any number between 0 and 255. The reason  for this is that the largest number you can fit into 8 bits is 255. You can see  this for yourself if you convert binary 11111111 into decimal:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;11111111  =&lt;br /&gt;&lt;br /&gt;(1 * 2^7) + (1 * 2^6) + (1 * 2^5) + (1 * 2^4) + (1 * 2^3)&lt;br /&gt;     + (1 * 2^2) + (1 * 2^1) + (1 * 2^0) =&lt;br /&gt;&lt;br /&gt;128 + 64 + 32 + 16 + 8 + 4 + 2 + 1 =&lt;br /&gt;&lt;br /&gt;255&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="last-para"&gt;The largest number that you can hold in 16 bits is 65535. The  largest number you can hold in 32 bits is 4294967295 (4 billion). The largest  number you can hold in 64 bits is 18,446,744,073,709,551,615. The largest number  you can hold in 128 bits is 340,282,366,920,938,463,463,374,607,431,768,211,456.  Anyway, you see the picture. For x86 processors, most of the time you will deal  with 4-byte numbers (32 bits), because that's the size of the registers.&lt;/p&gt;&lt;div class="section"&gt; &lt;h2 class="first-section-title"&gt;&lt;a name="300"&gt;&lt;/a&gt;&lt;a name="ch10lev1sec2"&gt;&lt;/a&gt;Truth,  Falsehood, and Binary Numbers&lt;/h2&gt;&lt;a name="301"&gt;&lt;/a&gt;&lt;a name="IDX-187"&gt;&lt;/a&gt; &lt;p class="para"&gt;Now we've seen that the computer stores everything as sequences of  1's and 0's. Let's look at some other uses of this. What if, instead of looking  at a sequence of bits as a number, we instead looked at it as a set of switches.  For example, let's say there are four switches that control lighting in the  house. We have a switch for outside lights, a switch for the hallway lights, a  switch for the living room lights, and a switch for the bedroom lights. We could  make a little table showing which of these were on and off, like so:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;Outside   Hallway   Living Room   Bedroom&lt;br /&gt;On        Off         On          On&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;It's obvious from looking at this that all of the lights are on  except the hallway ones. Now, instead of using the words "On" and "Off", let's  use the numbers 1 and 0. 1 will represent on, and 0 will represent off. So, we  could represent the same information as&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;Outside   Hallway   Living Room   Bedroom&lt;br /&gt;1         0            1          1&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;Now, instead of having labels on the light switches, let's say we  just memorized which position went with which switch. Then, the same information  could be represented as&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;1            0            1          1&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;or as&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;1011&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;This is just one of many ways you can use the computers storage  locations to represent more than just numbers. The computers memory just sees  numbers, but programmers can use these numbers to represent anything their  imaginations can &lt;a name="302"&gt;&lt;/a&gt;&lt;a name="IDX-188"&gt;&lt;/a&gt;come up with. They just  sometimes have to be creative when figuring out the best representation.&lt;/p&gt; &lt;p class="para"&gt;Not only can you do regular arithmetic with binary numbers, they  also have a few operations of their own, called binary or logical operations .  The standard binary operations are&lt;/p&gt; &lt;ul class="itemizedlist"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;AND&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;OR&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;NOT&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;XOR&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p class="para"&gt;Before we look at examples, I'll describe them for you. AND takes  two bits and returns one bit. AND will return a 1 only if both bits are 1, and a  0 otherwise. For example, 1 AND 1 is 1, but 1 AND 0 is 0, 0 AND 1 is 0, and 0  AND 0 is 0.&lt;/p&gt; &lt;p class="para"&gt;OR takes two bits and returns one bit. It will return 1 if either  of the original bits is 1. For example, 1 OR 1 is 1, 1 OR 0 is one, 0 OR 1 is 1,  but 0 OR 0 is 0.&lt;/p&gt; &lt;p class="para"&gt;NOT only takes one bit and returns its opposite. NOT 1 is 0 and  NOT 0 is 1.&lt;/p&gt; &lt;p class="para"&gt;Finally, XOR is like OR, except it returns 0 if both bits are  1.&lt;/p&gt; &lt;p class="para"&gt;Computers can do these operations on whole registers at a time.  For example, if a register has 10100010101010010101101100101010 and another one  has 10001000010101010101010101111010, you can run any of these operations on the  whole registers. For example, if we were to AND them, the computer will run from  the first bit to the 32nd and run the AND operation on that bit in both  registers. In this case:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;10100010101010010101101100101010 AND&lt;br /&gt;10001000010101010101010101111010&lt;br /&gt;--------------------------------&lt;br /&gt;10000000000000010101000100101010&lt;br /&gt;&lt;a name="303"&gt;&lt;/a&gt;&lt;a name="IDX-189"&gt;&lt;/a&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;You'll see that the resulting set of bits only has a one where &lt;i class="emphasis"&gt;both&lt;/i&gt; numbers had a one, and in every other position it has a  zero. Let's look at what an OR looks like:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;10100010101010010101101100101010 OR&lt;br /&gt;10001000010101010101010101111010&lt;br /&gt;--------------------------------&lt;br /&gt;10101010111111010101111101111010&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;In this case, the resulting number has a 1 where either number has  a 1 in the given position. Let's look at the NOT operation:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;NOT 10100010101010010101101100101010&lt;br /&gt;------------------------------------&lt;br /&gt;01011101010101101010010011010101&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;This just reverses each digit. Finally, we have XOR, which is like  an OR, except if &lt;i class="emphasis"&gt;both&lt;/i&gt; digits are 1, it returns 0.&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;10100010101010010101101100101010 XOR&lt;br /&gt;10001000010101010101010101111010&lt;br /&gt;--------------------------------&lt;br /&gt;00101010111111000000111001010000&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;This is the same two numbers used in the OR operation, so you can  compare how they work. Also, if you XOR a number with itself, you will always  get 0, like this:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;10100010101010010101101100101010 XOR&lt;br /&gt;10100010101010010101101100101010&lt;br /&gt;--------------------------------&lt;br /&gt;00000000000000000000000000000000&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;These operations are useful for two reasons:&lt;/p&gt; &lt;ul class="itemizedlist"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;The computer can do them extremely fast&lt;/p&gt;&lt;a name="304"&gt;&lt;/a&gt;&lt;a name="IDX-190"&gt;&lt;/a&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;You can use them to compare many truth values at the same  time&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p class="para"&gt;You may not have known that different instructions execute at  different speeds. It's true, they do. And these operations are the fastest on  most processors. For example, you saw that XORing a number with itself produces  0. Well, the XOR operation is faster than the loading operation, so many  programmers use it to load a register with zero. For example, the code&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt; movl  $0, %eax&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;is often replaced by&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt; xorl  %eax, %eax&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;We'll discuss speed more in &lt;span class="chapterjump"&gt;Chapter 12&lt;/span&gt;, but I want you to see how  programmers often do tricky things, especially with these binary operators, to  make things fast. Now let's look at how we can use these operators to manipulate  true/false values. Earlier we discussed how binary numbers can be used to  represent any number of things. Let's use binary numbers to represent what  things my Dad and I like. First, let's look at the things I like:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;Food: yes&lt;br /&gt;Heavy Metal Music: yes&lt;br /&gt;Wearing Dressy Clothes: no&lt;br /&gt;Football: yes&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;Now, let's look at what my Dad likes:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;Food: yes&lt;br /&gt;Heavy Metal Music: no&lt;br /&gt;Wearing Dressy Clothes: yes&lt;br /&gt;Football: yes&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;Now, let's use a 1 to say yes we like something, and a 0 to say no  we don't. Now we have:&lt;/p&gt;&lt;a name="305"&gt;&lt;/a&gt;&lt;a name="IDX-191"&gt;&lt;/a&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;Me&lt;br /&gt;Food: 1&lt;br /&gt;Heavy Metal Music: 1&lt;br /&gt;Wearing Dressy Clothes: 0&lt;br /&gt;Football: 1&lt;br /&gt;&lt;br /&gt;Dad&lt;br /&gt;Food: 1&lt;br /&gt;Heavy Metal Music: 0&lt;br /&gt;Wearing Dressy Clothes: 1&lt;br /&gt;Football: 1&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;Now, if we just memorize which position each of these are in, we  have&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;Me&lt;br /&gt;1101&lt;br /&gt;&lt;br /&gt;Dad&lt;br /&gt;1011&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;Now, let's see we want to get a list of things both my Dad and I  like. You would use the AND operation. So&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;1101 AND&lt;br /&gt;1011&lt;br /&gt;--------&lt;br /&gt;1001&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;Which translates to&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;Things we both like&lt;br /&gt;Food: yes&lt;br /&gt;Heavy Metal Music: no&lt;br /&gt;Wearing Dressy Clothes: no&lt;br /&gt;Football: yes&lt;br /&gt;&lt;a name="306"&gt;&lt;/a&gt;&lt;a name="IDX-192"&gt;&lt;/a&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;Remember, the computer has no idea what the ones and zeroes  represent. That's your job and your program's job. If you wrote a program around  this representation your program would at some point examine each bit and have  code to tell the user what it's for (if you asked a computer what two people  agreed on and it answered 1001, it wouldn't be very useful). Anyway, let's say  we want to know the things that we disagree on. For that we would use XOR,  because it will return 1 only if one or the other is 1, but not both. So&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;1101 XOR&lt;br /&gt;1011&lt;br /&gt;--------&lt;br /&gt;0110&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;And I'll let you translate that back out.&lt;/p&gt; &lt;p class="para"&gt;The previous operations: AND, OR, NOT, and XOR are called &lt;i class="emphasis"&gt;boolean operators&lt;/i&gt; because they were first studied by George  Boole. So, if someone mentiones boolean operators or boolean algebra, you now  know what they are talking about.&lt;/p&gt; &lt;p class="para"&gt;In addition to the boolean operations, there are also two binary  operators that aren't boolean, shift and rotate. Shifts and rotates each do what  their name implies, and can do so to the right or the left. A left shift moves  each digit of a binary number one space to the left, puts a zero in the ones  spot, and chops off the furthest digit to the left. A left rotate does the same  thing, but takes the furthest digit to the left and puts it in the ones spot.  For example,&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;Shift left  10010111 = 00101110&lt;br /&gt;Rotate left 10010111 = 00101111&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;Notice that if you rotate a number for every digit it has (i.e. -  rotating a 32-bit number 32 times), you wind up with the same number you started  with. However, if you &lt;i class="emphasis"&gt;shift&lt;/i&gt; a number for every digit you  have, you wind up with 0. So, what are these shifts useful for? Well, if you  have binary numbers representing things, you use shifts to peek at each  individual value. Let's say, for instance, that we had my Dad's likes stored in  a register (32 bits). It would look like this:&lt;/p&gt;&lt;a name="307"&gt;&lt;/a&gt;&lt;a name="IDX-193"&gt;&lt;/a&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;00000000000000000000000000001011&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;Now, as we said previously, this doesn't work as program output.  So, in order to do output, we would need to do shifting and &lt;i class="emphasis"&gt;masking.&lt;/i&gt; Masking is the process of eliminating everything you  don't want. In this case, for every value we are looking for, we will shift the  number so that value is in the ones place, and then mask that digit so that it  is all we see. Masking is accomplished by doing an AND with a number that has  the bits we are interested in set to 1. For example, let's say we wanted to  print out whether my Dad likes dressy clothes or not. That data is the second  value from the right. So, we have to shift the number right 1 digit so it looks  like this:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;00000000000000000000000000000101&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;and then, we just want to look at that digit, so we mask it by  ANDing it with 00000000000000000000000000000001.&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;00000000000000000000000000000101 AND&lt;br /&gt;00000000000000000000000000000001&lt;br /&gt;-----------------------------------&lt;br /&gt;00000000000000000000000000000001&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;This will make the value of the register 1 if my Dad likes dressy  clothes, and 0 if he doesn't. Then we can do a comparison to 1 and print the  results. The code would look like this:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt; #NOTE - assume that the register %ebx holds&lt;br /&gt;#       my Dad's preferences&lt;br /&gt;&lt;br /&gt;movl  %ebx, %eax #This copies the information into %eax so&lt;br /&gt;             #we don't lose the original data&lt;br /&gt;&lt;br /&gt;shrl  $1, %eax   #This is the shift operator.  It stands&lt;br /&gt;             #for Shift Right Long.  This first number&lt;br /&gt;             #is the number of positions to shift,&lt;a name="308"&gt;&lt;/a&gt;&lt;a name="IDX-194"&gt;&lt;/a&gt;&lt;br /&gt;             #and the second is the register to shift&lt;br /&gt;&lt;br /&gt;#This does the masking&lt;br /&gt;andl  $0b00000000000000000000000000000001, %eax&lt;br /&gt;&lt;br /&gt;#Check to see if the result is 1 or 0&lt;br /&gt;cmpl  $0b00000000000000000000000000000001, %eax&lt;br /&gt;&lt;br /&gt;je    yes_he_likes_dressy_clothes&lt;br /&gt;&lt;br /&gt;jmp   no_he_doesnt_like_dressy_clothes&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;And then we would have two labels which printed something about  whether or not he likes dressy clothes and then exits. The 0b notation means  that what follows is a binary number. In this case it wasn't needed, because 1  is the same in any numbering system, but I put it there for clarity. We also  didn't need the 31 zeroes, but I put them in to make a point that the number you  are using is 32 bits.&lt;/p&gt; &lt;p class="para"&gt;When a number represents a set of options for a function or system  call, the individual true/false elements are called &lt;i class="emphasis"&gt;flags.&lt;/i&gt;  Many system calls have numerous options that are all set in the same register  using a mechanism like we've described. The &lt;span class="fixed"&gt;open&lt;/span&gt; system  call, for example, has as its second parameter a list of flags to tell the  operating system how to open the file. Some of the flags include:&lt;/p&gt; &lt;p class="para"&gt;&lt;span class="fixed"&gt;O_WRONLY&lt;/span&gt; &lt;/p&gt; &lt;ul class="simple-list"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;This flag is &lt;span class="fixed"&gt;0b00000000000000000000000000000001&lt;/span&gt; in binary, or &lt;span class="fixed"&gt;01&lt;/span&gt; in octal (or any number system for that matter). This says  to open the file in write-only mode.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p class="para"&gt;&lt;span class="fixed"&gt;O_RDWR&lt;/span&gt; &lt;/p&gt; &lt;ul class="simple-list"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;This flag is &lt;span class="fixed"&gt;0b00000000000000000000000000000010&lt;/span&gt; in binary, or &lt;span class="fixed"&gt;02&lt;/span&gt; in octal. This says to open the file for both reading and  writing.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;a name="309"&gt;&lt;/a&gt;&lt;a name="IDX-195"&gt;&lt;/a&gt; &lt;p class="para"&gt;&lt;span class="fixed"&gt;O_CREAT&lt;/span&gt; &lt;/p&gt; &lt;ul class="simple-list"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;This flag is &lt;span class="fixed"&gt;0b00000000000000000000000001000000&lt;/span&gt; in binary, or &lt;span class="fixed"&gt;0100&lt;/span&gt; in octal. It means to create the file if it doesn't  already exist.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p class="para"&gt;&lt;span class="fixed"&gt;O_TRUNC&lt;/span&gt; &lt;/p&gt; &lt;ul class="simple-list"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;This flag is &lt;span class="fixed"&gt;0b00000000000000000000001000000000&lt;/span&gt; in binary, or &lt;span class="fixed"&gt;01000&lt;/span&gt; in octal. It means to erase the contents of the file if  the file already exists.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p class="para"&gt;&lt;span class="fixed"&gt;O_APPEND&lt;/span&gt; &lt;/p&gt; &lt;ul class="simple-list"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;This flag is &lt;span class="fixed"&gt;0b00000000000000000000010000000000&lt;/span&gt; in binary, or &lt;span class="fixed"&gt;02000&lt;/span&gt; in octal. It means to start writing at the end of the  file rather than at the beginning.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p class="para"&gt;To use these flags, you simply OR them together in the combination  that you want. For example, to open a file in write-only mode, and have it  create the file if it doesn't exist, I would use &lt;span class="fixed"&gt;O_WRONLY&lt;/span&gt; (01) and &lt;span class="fixed"&gt;O_CREAT&lt;/span&gt; (0100).  OR'd together, I would have 0101.&lt;/p&gt; &lt;p class="para"&gt;Note that if you don't set either &lt;span class="fixed"&gt;O_WRONLY&lt;/span&gt; or &lt;span class="fixed"&gt;O_RDWR&lt;/span&gt;, then the file is  automatically opened in read-only mode (&lt;span class="fixed"&gt;O_RDONLY&lt;/span&gt;,  except that it isn't really a flag since it's zero).&lt;/p&gt; &lt;p class="last-para"&gt;Many functions and system calls use flags for options, as it  allows a single word to hold up to 32 possible options if each option is  represented by a single bit.&lt;/p&gt;&lt;h2 class="first-section-title"&gt;&lt;a name="310"&gt;&lt;/a&gt;&lt;a name="ch10lev1sec3"&gt;&lt;/a&gt;The  Program Status Register&lt;/h2&gt; &lt;p class="first-para"&gt;We've seen how bits on a register can be used to give the  answers of yes/no and true/false statements. On your computer, there is a  register called the &lt;i class="emphasis"&gt;program status register.&lt;/i&gt; This register  holds a lot of information about what happens in a computation. For example,  have you ever wondered what would happen if you &lt;a name="311"&gt;&lt;/a&gt;&lt;a name="IDX-196"&gt;&lt;/a&gt;added two numbers and the result was larger than would fit in a  register? The program status register has a flag called the carry flag. You can  test it to see if the last computation overflowed the register. There are flags  for a number of different statuses. In fact, when you do a compare (&lt;span class="fixed"&gt;cmpl&lt;/span&gt;) instruction, the result is stored in this register. The  conditional jump instructions (&lt;span class="fixed"&gt;jge&lt;/span&gt;, &lt;span class="fixed"&gt;jne&lt;/span&gt;, etc) use these results to tell whether or not they  should jump. &lt;span class="fixed"&gt;jmp&lt;/span&gt;, the unconditional jump, doesn't care  what is in the status register, since it is unconditional.&lt;/p&gt; &lt;p class="para"&gt;Let's say you needed to store a number larger than 32 bits. So,  let's say the number is 2 registers wide, or 64 bits. How could you handle this?  If you wanted to add two 64 bit numbers, you would add the least significant  registers first. Then, if you detected an carry, you could add I to the most  significant register. In fact, this is probably the way you learned to do  decimal addition. If the result in one column is more than 9, you simply carried  the number to the next most significant column. If you added 65 and 37, first  you add 7 and 4 to get 12. You keep the 2 in the right column, and carry the one  to the next column. There you add 6, 3, and the 1 you carried. This results in  10. So, you keep the zero in that column and carry the one to the next most  significant column, which is empty, so you just put the one there. Luckily, 32  bits is usually big enough to hold the numbers we use regularly.&lt;/p&gt; &lt;p class="last-para"&gt;Additional program status register flags are examined in &lt;span class="chapterjump"&gt;Appendix B&lt;/span&gt;.&lt;/p&gt;&lt;div class="section"&gt; &lt;h2 class="first-section-title"&gt;&lt;a name="312"&gt;&lt;/a&gt;&lt;a name="ch10lev1sec4"&gt;&lt;/a&gt;Other  Numbering Systems&lt;/h2&gt; &lt;p class="first-para"&gt;What we have studied so far only applies to positive  integers. However, real-world numbers are not always positive integers. Negative  numbers and numbers with decimals are also used.&lt;/p&gt; &lt;div class="section"&gt; &lt;h3 class="sect3-title"&gt;&lt;a name="313"&gt;&lt;/a&gt;&lt;a name="ch10lev2sec4"&gt;&lt;/a&gt;Floating-Point  Numbers&lt;/h3&gt; &lt;p class="first-para"&gt;So far, the only numbers we've dealt with are integers -  numbers with no decimal point. Computers have a general problem with numbers  with decimal points, &lt;a name="314"&gt;&lt;/a&gt;&lt;a name="IDX-197"&gt;&lt;/a&gt;because computers can  only store fixed-size, finite values. Decimal numbers can be any length,  including infinite length (think of a repeating decimal, like the result of 1 /  3).&lt;/p&gt; &lt;p class="para"&gt;The way a computer handles decimals is by storing them at a fixed  precision (number of significant bits). A computer stores decimal numbers in two  parts - the &lt;i class="emphasis"&gt;exponent&lt;/i&gt; and the &lt;i class="emphasis"&gt;mantissa.&lt;/i&gt; The mantissa contains the actual digits that will  be used, and the exponent is what magnitude the number is. For example, 12345.2  can be represented as 1.23452 * 10^4. The mantissa is 1.23452 and the exponent  is 4 with a base of 10. Computers, however, use a base of 2. All numbers are  stored as X.XXXXX * 2^XXXX. The number 1, for example, is stored as 1.00000 *  2^0. Separating the mantissa and the exponent into two different values is  called a &lt;i class="emphasis"&gt;floating point&lt;/i&gt; representation, because the  position of the significant digits with respect to the decimal point can vary  based on the exponent.&lt;/p&gt; &lt;p class="para"&gt;Now, the mantissa and the exponent are only so long, which leads  to some interesting problems. For example, when a computer stores an integer, if  you add 1 to it, the resulting number is one larger. This does not necessarily  happen with floating point numbers. If the number is sufficiently big, adding 1  to it might not even register in the mantissa (remember, both parts are only so  long). This affects several things, especially order of operations. If you add  1.0 to a given floating point number, it might not even affect the number if it  is large enough. For example, on x86 platforms, a four-byte floating-point  number, although it can represent very large numbers, cannot have 1.0 added to  it past 16777216.0, because it is no longer significant. The number no longer  changes when 1.0 is added to it. So, if there is a multiplication followed by an  addition it may give a different result than if the addition is performed  first.&lt;/p&gt; &lt;p class="para"&gt;You should note that it takes most computers a lot longer to do  floating-point arithmetic than it does integer arithmetic. So, for programs that  really need speed, integers are mostly used.&lt;/p&gt;&lt;a name="315"&gt;&lt;/a&gt;&lt;a name="IDX-198"&gt;&lt;/a&gt;&lt;/div&gt; &lt;div class="section"&gt; &lt;h3 class="sect3-title"&gt;&lt;a name="316"&gt;&lt;/a&gt;&lt;a name="ch10lev2sec5"&gt;&lt;/a&gt;Negative  Numbers&lt;/h3&gt; &lt;p class="first-para"&gt;How would you think that negative numbers on a computer  might be represented? One thought might be to use the first digit of a number as  the sign, so &lt;span class="fixed"&gt;00000000000000000000000000000001&lt;/span&gt; would  represent the number 1, and &lt;span class="fixed"&gt;10000000000000000000000000000001&lt;/span&gt; would represent -1. This  makes a lot of sense, and in fact some old processors work this way. However, it  has some problems. First of all, it takes a lot more circuitry to add and  subtract signed numbers represented this way. Even more problematic, this  representation has a problem with the number 0. In this system, you could have  both a negative and a positive 0. This leads to a lot of questions, like "should  negative zero be equal to positive zero?", and "What should the sign of zero be  in various circumstances?".&lt;/p&gt; &lt;p class="para"&gt;These problems were overcome by using a representation of negative  numbers called &lt;i class="emphasis"&gt;two's complement&lt;/i&gt; representation. To get the  negative representation of a number in two's complement form, you must perform  the following steps:&lt;/p&gt; &lt;ol class="orderedlist"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;Perform a NOT operation on the number&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;Add one to the resulting number&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt; &lt;p class="para"&gt;So, to get the negative of &lt;span class="fixed"&gt;00000000000000000000000000000001&lt;/span&gt;, you would first do a NOT  operation, which gives &lt;span class="fixed"&gt;1111111111111111111111111111110&lt;/span&gt;,  and then add one, giving &lt;span class="fixed"&gt;11111111111111111111111111111111&lt;/span&gt;. To get negative two, first  take &lt;span class="fixed"&gt;00000000000000000000000000000010&lt;/span&gt;. The NOT of that  number is &lt;span class="fixed"&gt;11111111111111111111111111111101&lt;/span&gt;. Adding one  gives &lt;span class="fixed"&gt;11111111111111111111111111111110&lt;/span&gt;. With this  representation, you can add numbers just as if they were positive, and come out  with the right answers. For example, if you add one plus negative one in binary,  you will notice that all of the numbers flip to zero. Also, the first digit  still carries the sign bit, making it simple to determine whether or not the  number is positive or negative. Negative numbers will always have a &lt;span class="fixed"&gt;1&lt;/span&gt; in the leftmost bit. This also changes which numbers are  valid for a given number of bits. With signed numbers, the possible magnitude of  the values is split to allow for both positive and negative numbers. For  example, a &lt;a name="317"&gt;&lt;/a&gt;&lt;a name="IDX-199"&gt;&lt;/a&gt;byte can normally have values up  to 255. A signed byte, however, can store values from -128 to 127.&lt;/p&gt; &lt;p class="para"&gt;One thing to note about the two's complement representation of  signed numbers is that, unlike unsigned quantities, if you increase the number  of bits, you can't just add zeroes to the left of the number. For example, let's  say we are dealing with four-bit quantities and we had the number -3, &lt;span class="fixed"&gt;1101&lt;/span&gt;. If we were to extend this into an eight-bit register,  we could not represent it as &lt;span class="fixed"&gt;00001101&lt;/span&gt; as this would  represent 13, not -3. When you increase the size of a signed quantity in two's  complement representation, you have to perform &lt;i class="emphasis"&gt;sign  extension.&lt;/i&gt; Sign extension means that you have to pad the left-hand side of  the quantity with whatever digit is in the sign digit when you add bits. So, if  we extend a negative number by 4 digits, we should fill the new digits with a 1.  If we extend a positive number by 4 digits, we should fill the new digits with a  0. So, the extension of -3 from four to eight bits will yield &lt;span class="fixed"&gt;11111101&lt;/span&gt;.&lt;/p&gt; &lt;p class="last-para"&gt;The x86 processor has different forms of several instructions  depending on whether they expect the quantities they operate on to be signed or  unsigned. These are listed in &lt;span class="chapterjump"&gt;Appendix B&lt;/span&gt;. For example, the x86 processor has both a  sign-preserving shift-right, &lt;span class="fixed"&gt;sarl&lt;/span&gt;, and a shift-right  which does not preserve the sign bit, &lt;span class="fixed"&gt;shrl&lt;/span&gt;.&lt;/p&gt;&lt;div class="section"&gt; &lt;h2 class="first-section-title"&gt;&lt;a name="318"&gt;&lt;/a&gt;&lt;a name="ch10lev1sec5"&gt;&lt;/a&gt;Octal and  Hexadecimal Numbers&lt;/h2&gt; &lt;p class="first-para"&gt;The numbering systems discussed so far have been decimal and  binary. However, two others are used common in computing - octal and  hexadecimal. In fact, they are probably written more often than binary. Octal is  a representation that only uses the numbers 0 through 7. So the octal number 10  is actually 8 in decimal because it is one group of eight. Octal 121 is decimal  81 (one group of 64 (8^2), two groups of 8, and one left over). What makes octal  nice is that every 3 binary digits make one octal digit (there is no such  grouping of binary digits into decimal). So 0 is 000, 1 is 001, 2 is 010, 3 is  011, 4 is 100, 5 is 101, 6 is 110, and 7 &lt;a name="319"&gt;&lt;/a&gt;&lt;a name="IDX-200"&gt;&lt;/a&gt;is  111.&lt;/p&gt; &lt;p class="para"&gt;Permissions in Linux are done using octal. This is because Linux  permissions are based on the ability to read, write and execute. The first bit  is the read permission, the second bit is the write permission, and the third  bit is the execute permission. So, 0 (000) gives no permissions, 6(110) gives  read and write permission, and 5 (101) gives read and execute permissions. These  numbers are then used for the three different sets of permissions - the owner,  the group, and everyone else. The number 0644 means read and write for the first  permission set, and read-only for the second and third set. The first permission  set is for the owner of the file. The third permission set is for the group  owner of the file. The last permission set is for everyone else. So, &lt;span class="fixed"&gt;0751&lt;/span&gt; means that the owner of the file can read, write, and  execute the file, the group members can read and execute the file, and everyone  else can only execute the file.&lt;/p&gt; &lt;p class="para"&gt;Anyway, as you can see, octal is used to group bits (binary  digits) into threes. The way the assembler knows that a number is octal is  because octal numbers are prefixed with a zero. For example 010 means 10 in  octal, which is 8 in decimal. If you just write 10 that means 10 in decimal. The  beginning zero is what differentiates the two. So, &lt;i class="emphasis"&gt;be careful  not to put any leading zeroes in front of decimal numbers, or they will be  interepreted as octal numbers&lt;/i&gt;!&lt;/p&gt; &lt;p class="para"&gt;Hexadecimal numbers (also called just "hex") use the numbers 1–15  for each digit. however, since 10–15 don't have their own numbers, hexadecimal  uses the letters &lt;span class="fixed"&gt;a&lt;/span&gt; through &lt;span class="fixed"&gt;f&lt;/span&gt;  to represent them. For example, the letter &lt;span class="fixed"&gt;a&lt;/span&gt; represents  10, the letter &lt;span class="fixed"&gt;b&lt;/span&gt; represents 11, and so on. 10 in  hexadecimal is 16 in decimal. In octal, each digit represented three bits. In  hexadecimal, each digit represents four bits. Every two digits is a full byte,  and eight digits is a 32-bit word. So you see, it is considerably easier to  write a hexadecimal number than it is to write a binary number, because it's  only a quarter as many digits. The most important number to remember in  hexadecimal is &lt;span class="fixed"&gt;f&lt;/span&gt;, which means that all bits are set.  So, if I want to set all of the bits of a register to 1, I can just do&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt; movl   $0xFFFFFFFF,  %eax&lt;br /&gt;&lt;a name="320"&gt;&lt;/a&gt;&lt;a name="IDX-201"&gt;&lt;/a&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;Which is considerably easier and less error-prone than writing&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;movl   $0b11111111111111111111111111111111,  %eax&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;Note also that hexadecimal numbers are prefixed with &lt;span class="fixed"&gt;0x&lt;/span&gt;. So, when we do&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt; int   $0x80&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;We are calling interrupt number 128 (8 groups of 16), or interrupt  number &lt;span class="fixed"&gt;0b00000000000000000000000010000000&lt;/span&gt;.&lt;/p&gt; &lt;p class="last-para"&gt;Hexadecimal and octal numbers take some getting used to, but  they are heavily used in computer programming. It might be worthwhile to make up  some numbers in hex and try to convert them back and forth to binary, decimal,  and octal.&lt;/p&gt;&lt;div class="chapter"&gt;&lt;a name="ch10"&gt;&lt;/a&gt; &lt;div class="section"&gt; &lt;h2 class="first-section-title"&gt;&lt;a name="321"&gt;&lt;/a&gt;&lt;a name="ch10lev1sec6"&gt;&lt;/a&gt;Order of  Bytes in a Word&lt;/h2&gt; &lt;p class="first-para"&gt;One thing that confuses many people when dealing with bits  and bytes on a low level is that, when bytes are written from registers to  memory, their bytes are written out least-significant-portion-first. &lt;sup&gt;[&lt;a href="http://www2.blogger.com/post-edit.g?blogID=8901974503278002812&amp;postID=7379902394750515448#ftn.N15" name="N15"&gt;1&lt;/a&gt;]&lt;/sup&gt; What most people expect is that if they  have a word in a register, say &lt;span class="fixed"&gt;0x5d 23 ef ee&lt;/span&gt; (the  spacing is so you can see where the bytes are), the bytes will be written to  memory in that order. However, on x86 processors, the bytes are actually written  in reverse order. In memory the bytes would be &lt;span class="fixed"&gt;0xee ef 23  5d&lt;/span&gt; on x86 processors. The bytes are written in reverse order from what  they would appear conceptually, but the bits within the bytes are ordered  normally.&lt;/p&gt; &lt;p class="para"&gt;Not all processors behave this way. The x86 processor is a &lt;i class="emphasis"&gt;little-endian&lt;/i&gt; processor, which means that it stores the  "little end", or least-significant byte of its words first.&lt;/p&gt;&lt;a name="322"&gt;&lt;/a&gt;&lt;a name="IDX-202"&gt;&lt;/a&gt; &lt;div class="figure"&gt;&lt;a name="323"&gt;&lt;/a&gt;&lt;span class="figuremediaobject"&gt;&lt;a href="http://www2.blogger.com/images/fig210%5F01%5F0%2Ejpg" target="_parent" name="IMG_4"&gt;&lt;/a&gt;&lt;/span&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_pYXuXAWhUJk/RcF1KZB51tI/AAAAAAAAAB0/zSMvQxrGtJA/s1600-h/Fig04.jpg"&gt;&lt;img style="cursor: pointer;" src="http://2.bp.blogspot.com/_pYXuXAWhUJk/RcF1KZB51tI/AAAAAAAAAB0/zSMvQxrGtJA/s320/Fig04.jpg" alt="" id="BLOGGER_PHOTO_ID_5026427480500197074" border="0" /&gt;&lt;/a&gt;&lt;a href="http://www2.blogger.com/images/fig210%5F01%5F0%2Ejpg" target="_parent" name="IMG_4"&gt;&lt;/a&gt;&lt;span class="figuremediaobject"&gt;&lt;a href="http://www2.blogger.com/images/fig210%5F01%5F0%2Ejpg" target="_parent" name="IMG_4"&gt;&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="figure-title"&gt;Register-to-memory transfers  on little-endian systems&lt;/span&gt; &lt;/div&gt; &lt;p class="para"&gt;Other processors are &lt;i class="emphasis"&gt;big-endian&lt;/i&gt; processors,  which means that they store the "big end", or most significant byte, of their  words first, the way we would naturally read a number.&lt;/p&gt;&lt;a name="324"&gt;&lt;/a&gt;&lt;a name="IDX-203"&gt;&lt;/a&gt; &lt;div class="figure"&gt;&lt;a name="325"&gt;&lt;/a&gt;&lt;span class="figuremediaobject"&gt;&lt;a href="http://www2.blogger.com/images/fig211%5F01%5F0%2Ejpg" target="_parent" name="IMG_5"&gt;&lt;/a&gt;&lt;/span&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_pYXuXAWhUJk/RcF1a5B51uI/AAAAAAAAAB8/LltsaaZhosk/s1600-h/Fig05.jpg"&gt;&lt;img style="cursor: pointer;" src="http://4.bp.blogspot.com/_pYXuXAWhUJk/RcF1a5B51uI/AAAAAAAAAB8/LltsaaZhosk/s320/Fig05.jpg" alt="" id="BLOGGER_PHOTO_ID_5026427763968038626" border="0" /&gt;&lt;/a&gt;&lt;a href="http://www2.blogger.com/images/fig211%5F01%5F0%2Ejpg" target="_parent" name="IMG_5"&gt;&lt;/a&gt;&lt;span class="figuremediaobject"&gt;&lt;a href="http://www2.blogger.com/images/fig211%5F01%5F0%2Ejpg" target="_parent" name="IMG_5"&gt;&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="figure-title"&gt;Register-to-memory transfers  on big-endian systems&lt;/span&gt; &lt;/div&gt; &lt;p class="para"&gt;This difference is not normally a problem (although it has sparked  many technical controversies throughout the years). Because the bytes are  reversed again (or not, if it is a big-endian processor) when being read back  into a register, the programmer usually never notices what order the bytes are  in. The byte-switching magic happens automatically behind the scenes during  register-to-memory transfers. However, the byte order can cause problems in  several instances:&lt;/p&gt; &lt;ul class="itemizedlist"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;If you try to read in several bytes at a time using movl but  deal with them on a byte-by-byte basis using the least significant byte (i.e. -  by using &lt;span class="fixed"&gt;%al&lt;/span&gt; and/or shifting of the register), this  will be in a different order than they appear in memory.&lt;/p&gt;&lt;a name="326"&gt;&lt;/a&gt;&lt;a name="IDX-204"&gt;&lt;/a&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;If you read or write files written for different  architectures, you may have to account for whatever order they write their bytes  in.&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;If you read or write to network sockets, you may have to  account for a different byte order in the protocol.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p class="last-para"&gt;As long as you are aware of the issue, it usually isn't a big  deal. For more in-depth look at byte order issues, you should read DAV's Endian  FAQ at &lt;a class="url" href="http://www.rdrop.com/%7Ecary/html/endian_faq.html" target="_top"&gt;http://www.rdrop.com/~cary/html/endian_faq.html&lt;/a&gt;, especially the  article "On Holy Wars and a Plea for Peace" by Daniel Cohen.&lt;/p&gt;&lt;/div&gt; &lt;div class="footnotes"&gt; &lt;div class="footnote"&gt; &lt;p&gt;&lt;sup&gt;[&lt;a href="http://www2.blogger.com/post-edit.g?blogID=8901974503278002812&amp;amp;postID=7379902394750515448#N15" name="ftn.N15"&gt;1&lt;/a&gt;]&lt;/sup&gt;&lt;i class="emphasis"&gt;Significance&lt;/i&gt; in this context is referring to which digit they  represent. For example, in the number 294, the digit 2 is the most significant  because it represents the hundreds place, 9 is the next most significant, and 4  is the least significant.&lt;/p&gt;&lt;h2 class="first-section-title"&gt;&lt;a name="327"&gt;&lt;/a&gt;&lt;a name="ch10lev1sec7"&gt;&lt;/a&gt;Converting Numbers for Display&lt;/h2&gt; &lt;p class="first-para"&gt;So far, we have been unable to display any number stored to  the user, except by the extremely limitted means of passing it through exit  codes. In this section, we will discuss converting positive numbers into strings  for display.&lt;/p&gt; &lt;p class="para"&gt;The function will be called &lt;span class="fixed"&gt;integer2string&lt;/span&gt;, and it will take two parameters - an integer  to convert and a string buffer filled with null characters (zeroes). The buffer  will be assumed to be big enough to store the entire number as a string.(at  least 11 characters long, to include a trailing null character).&lt;/p&gt; &lt;p class="para"&gt;Remember that the way that we see numbers is in base 10.  Therefore, to access the individual decimal digits of a number, we need to be  dividing by 10 and displaying the remainder for each digit. Therefore, the  process will look like this:&lt;/p&gt; &lt;ul class="itemizedlist"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;Divide the number by ten&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;The remainder is the current digit. Convert it to a  character and store it.&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;We are finished if the quotient is zero.&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;Otherwise, take the quotient and the next location in the  buffer and repeat the process.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;a name="328"&gt;&lt;/a&gt;&lt;a name="IDX-205"&gt;&lt;/a&gt; &lt;p class="para"&gt;The only problem is that since this process deals with the one's  place first, it will leave the number backwards. Therefore, we will have to  finish by reversing the characters. We will do this by storing the characters on  the stack as we compute them. This way, as we pop them back off to fill in the  buffer, it will be in the reverse order that we pushed them on.&lt;/p&gt; &lt;p class="para"&gt;The code for the function should be put in a file called &lt;span class="fixed"&gt;integer-to-string.s&lt;/span&gt; and should be entered as follows:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;#PURPOSE:  Convert an integer number to a decimal string&lt;br /&gt;#          for display&lt;br /&gt;#&lt;br /&gt;#INPUT:    A buffer large enough to hold the largest&lt;br /&gt;#          possible number&lt;br /&gt;#          An integer to convert&lt;br /&gt;#&lt;br /&gt;#OUTPUT:   The buffer will be overwritten with the&lt;br /&gt;#          decimal string&lt;br /&gt;#&lt;br /&gt;#Variables:&lt;br /&gt;#&lt;br /&gt;# %ecx will hold the count of characters processed&lt;br /&gt;# %eax will hold the current value&lt;br /&gt;# %edi will hold the base (10)&lt;br /&gt;#&lt;br /&gt;.equ ST_VALUE, 8&lt;br /&gt;.equ ST_BUFFER, 12&lt;br /&gt;&lt;br /&gt;.globl integer2string&lt;br /&gt;.type integer2string, @function&lt;br /&gt;integer2string:&lt;br /&gt;#Normal function beginning&lt;br /&gt;pushl %ebp&lt;br /&gt;movl  %esp, %ebp&lt;a name="329"&gt;&lt;/a&gt;&lt;a name="IDX-206"&gt;&lt;/a&gt;&lt;br /&gt;#Current character count&lt;br /&gt;movl  $0, %ecx&lt;br /&gt;&lt;br /&gt;#Move the value into position&lt;br /&gt;movl  ST_VALUE(%ebp), %eax&lt;br /&gt;&lt;br /&gt;#When we divide by 10, the 10&lt;br /&gt;#must be in a register or memory location&lt;br /&gt;movl  $10, %edi&lt;br /&gt;&lt;br /&gt;conversion_loop:&lt;br /&gt;#Division is actually performed on the&lt;br /&gt;#combined %edx:%eax register, so first&lt;br /&gt;#clear out %edx&lt;br /&gt;movl  $0, %edx&lt;br /&gt;&lt;br /&gt;#Divide %edx:%eax (which are implied) by 10.&lt;br /&gt;#Store the quotient in %eax and the remainder&lt;br /&gt;#in %edx (both of which are implied).&lt;br /&gt;divl  %edi&lt;br /&gt;&lt;br /&gt;#Quotient is in the right place.  %edx has&lt;br /&gt;#the remainder, which now needs to be converted&lt;br /&gt;#into a number.  So, %edx has a number that is&lt;br /&gt;#0 through 9.  You could also interpret this as&lt;br /&gt;#an index on the ASCII table starting from the&lt;br /&gt;#character '0'.  The ascii code for '0' plus zero&lt;br /&gt;#is still the ascii code for '0'.  The ascii code&lt;br /&gt;#for '0' plus 1 is the ascii code for the&lt;br /&gt;#character '1'.  Therefore, the following&lt;br /&gt;#instruction will give us the character for the&lt;br /&gt;#number stored in %edx&lt;br /&gt;addl  $'0', %edx&lt;br /&gt;&lt;br /&gt;#Now we will take this value and push it on the&lt;a name="330"&gt;&lt;/a&gt;&lt;a name="IDX-207"&gt;&lt;/a&gt;&lt;br /&gt;#stack.  This way, when we are done, we can just&lt;br /&gt;#pop off the characters one-by-one and they will&lt;br /&gt;#be in the right order.  Note that we are pushing&lt;br /&gt;#the whole register, but we only need the byte&lt;br /&gt;#in %dl (the last byte of the %edx register) for&lt;br /&gt;#the character.&lt;br /&gt;pushl %edx&lt;br /&gt;&lt;br /&gt;#Increment the digit count&lt;br /&gt;incl  %ecx&lt;br /&gt;&lt;br /&gt;#Check to see if %eax is zero yet, go to next&lt;br /&gt;#step if so.&lt;br /&gt;cmpl  $0, %eax&lt;br /&gt;je    end_conversion_loop&lt;br /&gt;&lt;br /&gt;#%eax already has its new value.&lt;br /&gt;&lt;br /&gt;jmp conversion_loop&lt;br /&gt;&lt;br /&gt;end_conversion_loop:&lt;br /&gt;#The string is now on the stack, if we pop it&lt;br /&gt;#off a character at a time we can copy it into&lt;br /&gt;#the buffer and be done.&lt;br /&gt;&lt;br /&gt;#Get the pointer to the buffer in %edx&lt;br /&gt;movl ST_BUFFER(%ebp), %edx&lt;br /&gt;&lt;br /&gt;copy_reversing_loop:&lt;br /&gt;#We pushed a whole register, but we only need&lt;br /&gt;#the last byte.  So we are going to pop off to&lt;br /&gt;#the entire %eax register, but then only move the&lt;br /&gt;#small part (%al) into the character string.&lt;br /&gt;popl  %eax&lt;br /&gt;movb  %al, (%edx)&lt;a name="331"&gt;&lt;/a&gt;&lt;a name="IDX-208"&gt;&lt;/a&gt;&lt;br /&gt;#Decreasing %ecx so we know when we are finished&lt;br /&gt;decl  %ecx&lt;br /&gt;#Increasing %edx so that it will be pointing to&lt;br /&gt;#the next byte&lt;br /&gt;incl  %edx&lt;br /&gt;&lt;br /&gt;#Check to see if we are finished&lt;br /&gt;cmpl  $0, %ecx&lt;br /&gt;#If so, jump to the end of the function&lt;br /&gt;je    end_copy_reversing_loop&lt;br /&gt;#Otherwise, repeat the loop&lt;br /&gt;jmp   copy_reversing_loop&lt;br /&gt;&lt;br /&gt;end_copy_reversing_loop:&lt;br /&gt;#Done copying.  Now write a null byte and return&lt;br /&gt;movb  $0, (%edx)&lt;br /&gt;&lt;br /&gt;movl  %ebp, %esp&lt;br /&gt;popl  %ebp&lt;br /&gt;ret&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;To show this used in a full program, use the following code, along  with the &lt;span class="fixed"&gt;count_chars&lt;/span&gt; and &lt;span class="fixed"&gt;write_newline&lt;/span&gt; functions written about in previous chapters.  The code should be in a file called &lt;span class="fixed"&gt;conversion-program.s.&lt;/span&gt; &lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt; .include "linux.s"&lt;br /&gt;&lt;br /&gt;.section .data&lt;br /&gt;&lt;br /&gt;#This is where it will be stored&lt;br /&gt;tmp_buffer:&lt;br /&gt;.ascii "\0\0\0\0\0\0\0\0\0\0\0"&lt;a name="332"&gt;&lt;/a&gt;&lt;a name="IDX-209"&gt;&lt;/a&gt;&lt;br /&gt;.section .text&lt;br /&gt;&lt;br /&gt;.globl _start&lt;br /&gt;_start:&lt;br /&gt;movl  %esp, %ebp&lt;br /&gt;&lt;br /&gt;#Storage for the result&lt;br /&gt;pushl $tmp_buffer&lt;br /&gt;#Number to convert&lt;br /&gt;pushl $824&lt;br /&gt;call  integer2string&lt;br /&gt;addl  $8, %esp&lt;br /&gt;&lt;br /&gt;#Get the character count for our system call&lt;br /&gt;pushl $tmp_buffer&lt;br /&gt;call  count_chars&lt;br /&gt;addl  $4, %esp&lt;br /&gt;&lt;br /&gt;#The count goes in %edx for SYS_WRITE&lt;br /&gt;movl  %eax, %edx&lt;br /&gt;&lt;br /&gt;#Make the system call&lt;br /&gt;movl  $SYS_ WRITE, %eax&lt;br /&gt;movl  $STDOUT, %ebx&lt;br /&gt;movl  $tmp_buffer, %ecx&lt;br /&gt;&lt;br /&gt;int   $LINUX_SYSCALL&lt;br /&gt;&lt;br /&gt;#Write a carriage return&lt;br /&gt;pushl $STDOUT&lt;br /&gt;call  write_newline&lt;br /&gt;&lt;br /&gt;#Exit&lt;br /&gt;movl  $SYS_EXIT, %eax&lt;a name="333"&gt;&lt;/a&gt;&lt;a name="IDX-210"&gt;&lt;/a&gt;&lt;br /&gt;movl  $0, %ebx&lt;br /&gt;int   $LINUX_SYSCALL&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;To build the program, issue the following commands:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;as integer-to-string.s -o integer-to-number.o&lt;br /&gt;as count-chars.s -o count-chars.o&lt;br /&gt;as write-newline.s -o write-newline.o&lt;br /&gt;as conversion-program.s -o conversion-program.o&lt;br /&gt;ld integer-to-number.o count-chars.o write-newline.o conversion-&lt;br /&gt;program.o -o conversion-program&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="last-para"&gt;To run just type &lt;span class="fixed"&gt;./conversion-program&lt;/span&gt; and the output should say &lt;span class="fixed"&gt;824.&lt;/span&gt;&lt;/p&gt;&lt;h2 class="first-section-title"&gt;&lt;a name="334"&gt;&lt;/a&gt;&lt;a name="ch10lev1sec8"&gt;&lt;/a&gt;Review&lt;/h2&gt; &lt;div class="section"&gt; &lt;h3 class="sect3-title"&gt;&lt;a name="335"&gt;&lt;/a&gt;&lt;a name="ch10lev2sec6"&gt;&lt;/a&gt;Know the  Concepts&lt;/h3&gt; &lt;ul class="itemizedlist"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;Convert the decimal number 5,294 to binary.&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;What number does 0x0234aeff represent? Specify in binary,  octal, and decimal.&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;Add the binary numbers 10111001 and 101011.&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;Multiply the binary numbers 1100 1010110.&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;Convert the results of the previous two problems into  decimal.&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;Describe how AND, OR, NOT, and XOR work.&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;What is masking for?&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;What number would you use for the flags of the &lt;span class="fixed"&gt;open&lt;/span&gt; system call if you wanted to open the file for writing,  and create the file if it doesn't exist?&lt;/p&gt;&lt;a name="336"&gt;&lt;/a&gt;&lt;a name="IDX-211"&gt;&lt;/a&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;How would you represent -55 in a thirty-two bit  register?&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;Sign-extend the previous quantity into a 64-bit  register.&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;Describe the difference between little-endian and big-endian  storage of words in memory.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt; &lt;div class="section"&gt; &lt;h3 class="sect3-title"&gt;&lt;a name="337"&gt;&lt;/a&gt;&lt;a name="ch10lev2sec7"&gt;&lt;/a&gt;Use the  Concepts&lt;/h3&gt; &lt;ul class="itemizedlist"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;Go back to previous programs that returned numeric results  through the exit status code, and rewrite them to print out the results instead  using our integer to string conversion function.&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;Modify the &lt;span class="fixed"&gt;integer2string&lt;/span&gt; code to  return results in octal rather than decimal.&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;Modify the &lt;span class="fixed"&gt;integer2string&lt;/span&gt; code so  that the conversion base is a parameter rather than hardcoded.&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;Write a function called &lt;span class="fixed"&gt;is_negative&lt;/span&gt;  that takes a single integer as a parameter and returns 1 if the parameter is  negative, and 0 if the parameter is positive.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt; &lt;div class="section"&gt; &lt;h3 class="sect3-title"&gt;&lt;a name="338"&gt;&lt;/a&gt;&lt;a name="ch10lev2sec8"&gt;&lt;/a&gt;Going  Further&lt;/h3&gt; &lt;ul class="itemizedlist"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;Modify the &lt;span class="fixed"&gt;integer2string&lt;/span&gt; code so  that the conversion base can be greater than 10 (this requires you to use  letters for numbers past 9).&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;Create a function that does the reverse of &lt;span class="fixed"&gt;integer2string&lt;/span&gt; called &lt;span class="fixed"&gt;number2integer&lt;/span&gt;  which takes a character string and converts it to a register-sized integer. Test  it by running that integer back through the &lt;span class="fixed"&gt;integer2string&lt;/span&gt; function and displaying the results.&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;Write a program that stores likes and dislikes into a single  machine word, and then compares two sets of likes and dislikes for  commonalities.&lt;/p&gt;&lt;a name="339"&gt;&lt;/a&gt;&lt;a name="IDX-212"&gt;&lt;/a&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;Write a program that reads a string of characters from STDIN  and converts them to a number.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8901974503278002812-7379902394750515448?l=programminggroundup.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://programminggroundup.blogspot.com/feeds/7379902394750515448/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8901974503278002812&amp;postID=7379902394750515448' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8901974503278002812/posts/default/7379902394750515448'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8901974503278002812/posts/default/7379902394750515448'/><link rel='alternate' type='text/html' href='http://programminggroundup.blogspot.com/2007/01/chapter-10-counting-like-computer.html' title='Chapter 10: Counting like a Computer'/><author><name>Admin</name><uri>http://www.blogger.com/profile/13783659974416042562</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_pYXuXAWhUJk/RcF1KZB51tI/AAAAAAAAAB0/zSMvQxrGtJA/s72-c/Fig04.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8901974503278002812.post-3284968477063416573</id><published>2007-01-31T18:26:00.000-08:00</published><updated>2008-12-08T14:18:10.266-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='x86'/><category scheme='http://www.blogger.com/atom/ns#' term='asm'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='assembly language'/><category scheme='http://www.blogger.com/atom/ns#' term='memory'/><title type='text'>Chapter 9: Intermediate Memory Topics</title><content type='html'>&lt;div class="section"&gt; &lt;h2 class="sect2-title"&gt;&lt;a name="239"&gt;&lt;/a&gt;&lt;a name="ch09lev1sec1"&gt;&lt;/a&gt;How a Computer  Views Memory&lt;/h2&gt; &lt;p class="first-para"&gt;Let's review how memory within a computer works. You may  also want to re-read &lt;span class="chapterjump"&gt;Chapter 2&lt;/span&gt;.&lt;/p&gt; &lt;p class="para"&gt;A computer looks at memory as a long sequence of numbered storage  locations. A sequence of &lt;i class="emphasis"&gt;millions&lt;/i&gt; of numbered storage  locations. Everything is stored in these locations. Your programs are stored  there, your data is stored there, everything. Each storage location looks like  every other one. The locations holding your program are just like the ones  holding your data. In fact, the computer has no idea which are which, except  that the executable file tells it where to start executing.&lt;/p&gt; &lt;p class="para"&gt;These storage locations are called bytes. The computer can combine  up to four of them together into a single word. Normally numeric data is  operated on a word at a time. As we mentioned, instructions are also stored in  this same memory. Each instruction is a different length. Most instructions take  up one or two storage locations for the instruction itself, and then storage  locations for the instruction's arguments. For example, the instruction&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt; movl data_items(,%edi,4), %ebx&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;takes up 7 storage locations. The first two hold the instruction,  the third one tells which registers to use, and the next four hold the storage  location of &lt;span class="fixed"&gt;data_items.&lt;/span&gt; In memory, instructions look  just like all the other numbers, and the instructions themselves can be moved  into and out of registers just like numbers, because that's what they are.&lt;/p&gt; &lt;p class="para"&gt;This chapter is focused on the details of computer memory. To get  started let's review some basic terms that we will be using in this  chapter:&lt;/p&gt;&lt;a name="240"&gt;&lt;/a&gt;&lt;a name="IDX-148"&gt;&lt;/a&gt; &lt;p class="para"&gt;Byte&lt;/p&gt; &lt;ul class="simple-list"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;This is the size of a storage location. On x86 processors, a  byte can hold numbers between 0 and 255.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p class="para"&gt;Word&lt;/p&gt; &lt;ul class="simple-list"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;This is the size of a normal register. On x86 processors, a  word is four bytes long. Most computer operations handle a word at a  time.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p class="para"&gt;Address&lt;/p&gt; &lt;ul class="simple-list"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;An address is a number that refers to a byte in memory. For  example, the first byte on a computer has an address of 0, the second has an  address of 1, and so on. &lt;sup&gt;[&lt;a href="http://www2.blogger.com/post-edit.g?blogID=8901974503278002812&amp;postID=3284968477063416573#ftn.N73" name="N73"&gt;1&lt;/a&gt;]&lt;/sup&gt; Every  piece of data on the computer not in a register has an address. The address of  data which spans several bytes is the same as the address of its first byte.&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;Normally, we don't ever type the numeric address of  anything, but we let the assembler do it for us. When we use labels in code, the  symbol used in the label will be equivalent to the address it is labelling. The  assembler will then replace that symbol with its address wherever you use it in  your program. For example, say you have the following code:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt; .section .data&lt;br /&gt;my_data:&lt;br /&gt;.long 2, 3, 4&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;Now, any time in the program that &lt;span class="fixed"&gt;my_data&lt;/span&gt; is used, it will be replaced by the address of the  first value of the &lt;span class="fixed"&gt;.long&lt;/span&gt; directive.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p class="para"&gt;Pointer&lt;/p&gt; &lt;ul class="simple-list"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;A pointer is a register or memory word whose value is an  address. In our programs we use &lt;span class="fixed"&gt;%ebp&lt;/span&gt; as a pointer to  the current stack frame. All base &lt;a name="241"&gt;&lt;/a&gt;&lt;a name="IDX-149"&gt;&lt;/a&gt;pointer  addressing involves pointers. Programming uses a lot of pointers, so it's an  important concept to grasp.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt; &lt;div class="footnotes"&gt; &lt;div class="footnote"&gt; &lt;p&gt;&lt;sup&gt;[&lt;a href="http://www2.blogger.com/post-edit.g?blogID=8901974503278002812&amp;amp;postID=3284968477063416573#N73" name="ftn.N73"&gt;1&lt;/a&gt;]&lt;/sup&gt;You actually never use  addresses this low, but it works for discussion.&lt;/p&gt;&lt;div class="section"&gt; &lt;h2 class="first-section-title"&gt;&lt;a name="242"&gt;&lt;/a&gt;&lt;a name="ch09lev1sec2"&gt;&lt;/a&gt;The  Memory Layout of a Linux Program&lt;/h2&gt; &lt;p class="first-para"&gt;When you program is loaded into memory, each &lt;span class="fixed"&gt;.section&lt;/span&gt; is loaded into its own region of memory. All of the  code and data declared in each section is brought together, even if they were  separated in your source code.&lt;/p&gt; &lt;p class="para"&gt;The actual instructions (the &lt;span class="fixed"&gt;.text&lt;/span&gt;  section) are loaded at the address 0x08048000 (numbers starting with 0x are in  hexadecimal, which will be discussed in &lt;span class="chapterjump"&gt;Chapter 10&lt;/span&gt;). &lt;sup&gt;[&lt;a href="http://www2.blogger.com/post-edit.g?blogID=8901974503278002812&amp;postID=3284968477063416573#ftn.N29" name="N29"&gt;2&lt;/a&gt;]&lt;/sup&gt; The &lt;span class="fixed"&gt;.data&lt;/span&gt; section is loaded  immediately after that, followed by the &lt;span class="fixed"&gt;.bss&lt;/span&gt;  section.&lt;/p&gt; &lt;p class="para"&gt;The last byte that can be addressed on Linux is location  Oxbfffffff. Linux starts the stack here and grows it downward toward the other  sections. Between them is a huge gap. The initial layout of the stack is as  follows: At the bottom of the stack (the bottom of the stack is the top address  of memory - see &lt;span class="chapterjump"&gt;Chapter 4&lt;/span&gt;), there is a word of memory that is zero. After  that comes the null-terminated name of the program using ASCII characters. After  the program name comes the program's environment variables (these are not  important to us in this book). Then come the program's command-line arguments.  These are the values that the user typed in on the command line to run this  program. When we run &lt;span class="fixed"&gt;as&lt;/span&gt;, for example, we give it  several arguments - &lt;span class="fixed"&gt;as&lt;/span&gt;, &lt;span class="fixed"&gt;sourcefile.s&lt;/span&gt;,&lt;span class="fixed"&gt;-o&lt;/span&gt;, and &lt;span class="fixed"&gt;objectfile. o.&lt;/span&gt; After these, we have the number of arguments  that were used. When the program begins, this is where the stack pointer, &lt;span class="fixed"&gt;%esp&lt;/span&gt;, is pointing. Further pushes on the stack move &lt;span class="fixed"&gt;%esp&lt;/span&gt; down in memory. For example, the instruction&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt; pushl %eax&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;is equivalent to&lt;/p&gt;&lt;a name="243"&gt;&lt;/a&gt;&lt;a name="IDX-150"&gt;&lt;/a&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt; movl %eax, (%esp)&lt;br /&gt;subl $4, %esp&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;Likewise, the instruction&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt; popl %eax&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;is the same as&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt; movl (%esp), %eax&lt;br /&gt;addl $4, %esp&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;Your program's data region starts at the bottom of memory and goes  up. The stack starts at the top of memory, and moves downward with each push.  This middle part between the stack and your program's data sections is  inaccessible memory - you are not allowed to access it until you tell the kernel  that you need it. &lt;sup&gt;[&lt;a href="http://www2.blogger.com/post-edit.g?blogID=8901974503278002812&amp;amp;postID=3284968477063416573#ftn.N109" name="N109"&gt;3&lt;/a&gt;]&lt;/sup&gt; If you try,  you will get an error (the error message is usually "segmentation fault"). The  same will happen if you try to access data before the beginning of your program,  0x08048000. The last accessible memory address to your program is called the &lt;i class="emphasis"&gt;system break&lt;/i&gt; (also called the &lt;i class="emphasis"&gt;current  break&lt;/i&gt; or just the &lt;i class="emphasis"&gt;break&lt;/i&gt;).&lt;/p&gt;&lt;a name="244"&gt;&lt;/a&gt;&lt;a name="IDX-151"&gt;&lt;/a&gt; &lt;div class="figure"&gt;&lt;a name="245"&gt;&lt;/a&gt;&lt;span class="figuremediaobject"&gt;&lt;a href="http://www2.blogger.com/images/fig159%5F01%5F0%2Ejpg" target="_parent" name="IMG_3"&gt;&lt;/a&gt;&lt;/span&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_pYXuXAWhUJk/RcF0u5B51sI/AAAAAAAAABo/mZeE9f08GIA/s1600-h/Fig03.jpg"&gt;&lt;img style="cursor: pointer;" src="http://4.bp.blogspot.com/_pYXuXAWhUJk/RcF0u5B51sI/AAAAAAAAABo/mZeE9f08GIA/s320/Fig03.jpg" alt="" id="BLOGGER_PHOTO_ID_5026427008053794498" border="0" /&gt;&lt;/a&gt;&lt;a href="http://www2.blogger.com/images/fig159%5F01%5F0%2Ejpg" target="_parent" name="IMG_3"&gt;&lt;/a&gt;&lt;span class="figuremediaobject"&gt;&lt;a href="http://www2.blogger.com/images/fig159%5F01%5F0%2Ejpg" target="_parent" name="IMG_3"&gt;&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="figure-title"&gt;Memory Layout of a Linux  Program at Startup&lt;/span&gt; &lt;/div&gt;&lt;/div&gt; &lt;div class="footnotes"&gt; &lt;div class="footnote"&gt; &lt;p&gt;&lt;sup&gt;[&lt;a href="http://www2.blogger.com/post-edit.g?blogID=8901974503278002812&amp;postID=3284968477063416573#N29" name="ftn.N29"&gt;2&lt;/a&gt;]&lt;/sup&gt;Addresses mentioned in this  chapter are not set in stone and may vary based on kernel version.&lt;/p&gt;&lt;/div&gt; &lt;div class="footnote"&gt; &lt;p&gt;&lt;sup&gt;[&lt;a href="http://www2.blogger.com/post-edit.g?blogID=8901974503278002812&amp;amp;postID=3284968477063416573#N109" name="ftn.N109"&gt;3&lt;/a&gt;]&lt;/sup&gt;The stack can access it as it  grows downward, and you can access the stack regions through &lt;span class="fixed"&gt;%esp.&lt;/span&gt; However, your program's data section doesn't grow that  way. The way to grow that will be explained shortly.&lt;/p&gt;&lt;div class="chapter"&gt;&lt;a name="ch09"&gt;&lt;/a&gt; &lt;div class="section"&gt; &lt;h2 class="first-section-title"&gt;&lt;a name="246"&gt;&lt;/a&gt;&lt;a name="ch09lev1sec3"&gt;&lt;/a&gt;Every  Memory Address is a Lie&lt;/h2&gt; &lt;p class="first-para"&gt;So, why does the computer not allow you to access memory in  the break area? To answer this question, we will have to delve into the depths  of how your computer really handles memory.&lt;/p&gt; &lt;p class="para"&gt;You may have wondered, since every program gets loaded into the  same place in &lt;a name="247"&gt;&lt;/a&gt;&lt;a name="IDX-152"&gt;&lt;/a&gt;memory, don't they step on  each other, or overwrite each other? It would seem so. However, as a program  writer, you only access &lt;i class="emphasis"&gt;virtual memory.&lt;/i&gt; &lt;/p&gt; &lt;p class="para"&gt;&lt;i class="emphasis"&gt;Physical memory&lt;/i&gt; refers to the actual RAM  chips inside your computer and what they contain. It's usually between 16 and  512 Megabytes on modern computers. If we talk about a &lt;i class="emphasis"&gt;physical  memory address,&lt;/i&gt; we are talking about where exactly on these chips a piece of  memory is located. Virtual memory is the way &lt;i class="emphasis"&gt;your program&lt;/i&gt;  thinks about memory. Before loading your program, Linux finds an empty physical  memory space large enough to fit your program, and then tells the processor to  pretend that this memory is actually at the address 0x0804800 to load your  program into. Confused yet? Let me explain further.&lt;/p&gt; &lt;p class="para"&gt;Each program gets its own sandbox to play in. Every program  running on your computer thinks that it was loaded at memory address 0x0804800,  and that its stack starts at Oxbffffff. When Linux loads a program, it finds a  section of unused memory, and then tells the processor to use that section of  memory as the address 0x0804800 for this program. The address that a program  believes it uses is called the virtual address, while the actual address on the  chips that it refers to is called the physical address. The process of assigning  virtual addresses to physical addresses is called &lt;i class="emphasis"&gt;mapping.&lt;/i&gt;  &lt;/p&gt; &lt;p class="para"&gt;Earlier we talked about the inaccessible memory between the &lt;span class="fixed"&gt;.bss&lt;/span&gt; and the stack, but we didn't talk about why it was  there. The reason is that this region of virtual memory addresses hasn't been  mapped onto physical memory addresses. The mapping process takes up considerable  time and space, so if every possible virtual address of every possible program  were mapped, you would not have enough physical memory to even run one program.  So, the break is the beginning of the area that contains unmapped memory. With  the stack, however, Linux will automatically map in memory that is accessed from  stack pushes.&lt;/p&gt; &lt;p class="para"&gt;Of course, this is a very simplified view of virtual memory. The  full concept is much more advanced. For example, Virtual memory can be mapped to  more than just physical memory; it can be mapped to disk as well. Swap  partitions on Linux allow Linux's virtual memory system to map memory not only  to physical RAM, &lt;a name="248"&gt;&lt;/a&gt;&lt;a name="IDX-153"&gt;&lt;/a&gt;but also to disk blocks as  well. For example, let's say you only have 16 Megabytes of physical memory.  Let's also say that 8 Megabytes are being used by Linux and some basic  applications, and you want to run a program that requires 20 Megabytes of  memory. Can you? The answer is yes, but only if you have set up a swap  partition. What happens is that after all of your remaining 8 Megabytes of  physical memory have been mapped into virtual memory, Linux starts mapping parts  of your application's virtual memory to disk blocks. So, if you access a  "memory" location in your program, that location may not actually be in memory  at all, but on disk. As the programmer you won't know the difference, though,  because it is all handled behind the scenes by Linux.&lt;/p&gt; &lt;p class="para"&gt;Now, x86 processors cannot run instructions directly from disk,  nor can they access data directly from disk. This requires the help of the  operating system. When you try to access memory that is mapped to disk, the  processor notices that it can't service your memory request directly. It then  asks Linux to step in. Linux notices that the memory is actually on disk.  Therefore, it moves some data that is currently in memory onto disk to make  room, and then moves the memory being accessed from the disk back into physical  memory. It then adjusts the processor's virtual-to-physical memory lookup tables  so that it can find the memory in the new location. Finally, Linux returns  control to the program and restarts it at the instruction which was trying to  access the data in the first place. This instruction can now be completed  successfully, because the memory is now in physical RAM. &lt;sup&gt;[&lt;a href="http://www2.blogger.com/post-edit.g?blogID=8901974503278002812&amp;postID=3284968477063416573#ftn.N53" name="N53"&gt;4&lt;/a&gt;]&lt;/sup&gt; &lt;/p&gt; &lt;p class="para"&gt;Here is an overview of the way memory accesses are handled under  Linux:&lt;/p&gt; &lt;ul class="itemizedlist"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;The program tries to load memory from a virtual address.&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;The processor, using tables supplied by Linux, transforms  the virtual memory address into a physical memory address on the fly.&lt;/p&gt;&lt;a name="249"&gt;&lt;/a&gt;&lt;a name="IDX-154"&gt;&lt;/a&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;If the processor does not have a physical address listed for  the memory address, it sends a request to Linux to load it.&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;Linux looks at the address. If it is mapped to a disk  location, it continues on to the next step. Otherwise, it terminates the program  with a segmentation fault error.&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;If there is not enough room to load the memory from disk,  Linux will move another part of the program or another program onto disk to make  room.&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;Linux then moves the data into a free physical memory  address.&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;Linux updates the processor's virtual-to-physical memory  mapping tables to reflect the changes.&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;Linux restores control to the program, causing it to  re-issue the instruction which caused this process to happen.&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;The processor can now handle the instruction using the  newly-loaded memory and translation tables.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p class="para"&gt;It's a lot of work for the operating system, but it gives the user  and the programmer great flexibility when it comes to memory management.&lt;/p&gt; &lt;p class="para"&gt;Now, in order to make the process more efficient, memory is  separated out into groups called &lt;i class="emphasis"&gt;pages.&lt;/i&gt; When running Linux  on x86 processors, a page is 4096 bytes of memory. All of the memory mappings  are done a page at a time. Physical memory assignment, swapping, mapping, etc.  are all done to memory pages instead of individual memory addresses. What this  means to you as a programmer is that whenever you are programming, you should  try to keep most memory accesses within the same basic range of memory, so you  will only need a page or two of memory at a time. Otherwise, Linux may have to  keep moving pages on and off of disk to satisfy your memory needs. Disk access  is slow, so this can really slow down your program.&lt;/p&gt; &lt;p class="para"&gt;Sometimes so many programs can be loaded that there is hardly  enough physical memory for them. They wind up spending more time just swapping  memory on &lt;a name="250"&gt;&lt;/a&gt;&lt;a name="IDX-155"&gt;&lt;/a&gt;and off of disk than they do  actually processing it. This leads to a condition called &lt;i class="emphasis"&gt;swap  death&lt;/i&gt; which leads to your system being unresponsive and unproductive. It's  usually usually recoverable if you start terminating your memory-hungry  programs, but it's a pain.&lt;/p&gt; &lt;ul class="simple-list"&gt;&lt;li class="first-listitem"&gt; &lt;p class="para"&gt;&lt;b&gt;Resident Set Size:&lt;/b&gt; The amount of memory that your program  currently has in physical memory is called its resident set size, and can be  viewed by using the program &lt;span class="fixed"&gt;top&lt;/span&gt;. The resident set size  is listed under the column labelled "RSS".&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt; &lt;div class="footnotes"&gt; &lt;div class="footnote"&gt; &lt;p&gt;&lt;sup&gt;[&lt;a href="http://www2.blogger.com/post-edit.g?blogID=8901974503278002812&amp;amp;postID=3284968477063416573#N53" name="ftn.N53"&gt;4&lt;/a&gt;]&lt;/sup&gt;Note that not only can Linux  have a virtual address map to a different physical address, it can also move  those mappings around as needed.&lt;/p&gt;&lt;div class="chapter"&gt;&lt;a name="ch09"&gt;&lt;/a&gt; &lt;div class="section"&gt; &lt;h2 class="first-section-title"&gt;&lt;a name="251"&gt;&lt;/a&gt;&lt;a name="ch09lev1sec4"&gt;&lt;/a&gt;Getting  More Memory&lt;/h2&gt; &lt;p class="first-para"&gt;We now know that Linux maps all of our virtual memory into  physical memory or swap. If you try to access a piece of virtual memory that  hasn't been mapped yet, it triggers an error known as a segmentation fault,  which will terminate your program. The program break point, if you remember, is  the last valid address you can use. Now, this is all great if you know  beforehand how much storage you will need. You can just add all the memory you  need to your &lt;span class="fixed"&gt;.data&lt;/span&gt; or &lt;span class="fixed"&gt;.bss&lt;/span&gt;  sections, and it will all be there. However, let's say you don't know how much  memory you will need. For example, with a text editor, you don't know how long  the person's file will be. You could try to find a maximum file size, and just  tell the user that they can't go beyond that, but that's a waste if the file is  small. Therefore Linux has a facility to move the break point to accomodate an  application's memory needs.&lt;/p&gt; &lt;p class="para"&gt;If you need more memory, you can just tell Linux where you want  the new break point to be, and Linux will map all the memory you need between  the current and new break point, and then move the break point to the spot you  specify. That memory is now available for your program to use. The way we tell  Linux to move the break point is through the &lt;span class="fixed"&gt;brk&lt;/span&gt; system  call. The &lt;span class="fixed"&gt;brk&lt;/span&gt; system call is call number &lt;a name="252"&gt;&lt;/a&gt;&lt;a name="IDX-156"&gt;&lt;/a&gt;45 (which will be in &lt;span class="fixed"&gt;%eax&lt;/span&gt;). &lt;span class="fixed"&gt;%ebx&lt;/span&gt; should be loaded with  the requested breakpoint. Then you call &lt;span class="fixed"&gt;int $0x80&lt;/span&gt; to  signal Linux to do its work. After mapping in your memory, Linux will return the  new break point in &lt;span class="fixed"&gt;%eax.&lt;/span&gt; The new break point might  actually be larger than what you asked for, because Linux rounds up to the  nearest page. If there is not enough physical memory or swap to fulfill your  request, Linux will return a zero in &lt;span class="fixed"&gt;%eax.&lt;/span&gt; Also, if you  call &lt;span class="fixed"&gt;brk&lt;/span&gt; with a zero in &lt;span class="fixed"&gt;%ebx&lt;/span&gt;,  it will simply return the last usable memory address.&lt;/p&gt; &lt;p class="para"&gt;The problem with this method is keeping track of the memory we  request. Let's say I need to move the break to have room to load a file, and  then need to move a break again to load another file. Let's say I then get rid  of the first file. You now have a giant gap in memory that's mapped, but that  you aren't using. If you continue to move the break in this way for each file  you load, you can easily run out of memory. So, what is needed is a &lt;i class="emphasis"&gt;memory manager.&lt;/i&gt; &lt;/p&gt; &lt;p class="para"&gt;A memory manager is a set of routines that takes care of the dirty  work of getting your program memory for you. Most memory managers have two basic  functions - &lt;span class="fixed"&gt;allocate&lt;/span&gt; and &lt;span class="fixed"&gt;deallocate&lt;/span&gt;. &lt;sup&gt;[&lt;a href="http://www2.blogger.com/post-edit.g?blogID=8901974503278002812&amp;postID=3284968477063416573#ftn.N80" name="N80"&gt;5&lt;/a&gt;]&lt;/sup&gt;  Whenever you need a certain amount of memory, you can simply tell &lt;span class="fixed"&gt;allocate&lt;/span&gt; how much you need, and it will give you back an  address to the memory. When you're done with it, you tell &lt;span class="fixed"&gt;deallocate&lt;/span&gt; that you are through with it. &lt;span class="fixed"&gt;allocate&lt;/span&gt; will then be able to reuse the memory. This pattern  of memory management is called &lt;i class="emphasis"&gt;dynamic memory allocation.&lt;/i&gt;  This minimizes the number of "holes" in your memory, making sure that you are  making the best use of it you can. The pool of memory used by memory managers is  commonly referred to as &lt;i class="emphasis"&gt;the heap.&lt;/i&gt; &lt;/p&gt; &lt;p class="last-para"&gt;The way memory managers work is that they keep track of where  the system break is, and where the memory that you have allocated is. They mark  each block of memory in the heap as being used or unused. When you request  memory, the memory manager checks to see if there are any unused blocks of the  appropriate size. If not, it calls the &lt;span class="fixed"&gt;brk&lt;/span&gt; system call  to request more memory. When you free &lt;a name="253"&gt;&lt;/a&gt;&lt;a name="IDX-157"&gt;&lt;/a&gt;memory  it marks the block as unused so that future requests can retrieve it. In the &lt;a class="chapterjump" href="http://www2.blogger.com/LiB0048.html#254" target="_parent"&gt;next section&lt;/a&gt; we  will look at building our own memory manager.&lt;/p&gt;&lt;/div&gt; &lt;div class="footnotes"&gt; &lt;div class="footnote"&gt; &lt;p&gt;&lt;sup&gt;[&lt;a href="http://www2.blogger.com/post-edit.g?blogID=8901974503278002812&amp;amp;postID=3284968477063416573#N80" name="ftn.N80"&gt;5&lt;/a&gt;]&lt;/sup&gt;The function names usually  aren't &lt;span class="fixed"&gt;allocate&lt;/span&gt; and &lt;span class="fixed"&gt;deallocate&lt;/span&gt;, but the functionality will be the same. In the C  programming language, for example, they are named &lt;span class="fixed"&gt;malloc&lt;/span&gt; and &lt;span class="fixed"&gt;free&lt;/span&gt;.&lt;/p&gt;&lt;div class="section"&gt; &lt;h2 class="first-section-title"&gt;&lt;a name="254"&gt;&lt;/a&gt;&lt;a name="ch09lev1sec5"&gt;&lt;/a&gt;A Simple  Memory Manager&lt;/h2&gt; &lt;p class="first-para"&gt;Here I will show you a simple memory manager. It is very  primitive but it shows the principles quite well. As usual, I will give you the  program first for you to look through. Afterwards will follow an in-depth  explanation. It looks long, but it is mostly comments.&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt; #PURPOSE: Program to manage memory usage - allocates&lt;br /&gt;#         and deallocates memory as requested&lt;br /&gt;#&lt;br /&gt;#NOTES:   The programs using these routines will ask&lt;br /&gt;#         for a certain size of memory.  We actually&lt;br /&gt;#         use more than that size, but we put it&lt;br /&gt;#         at the beginning, before the pointer&lt;br /&gt;#         we hand back.  We add a size field and&lt;br /&gt;#         an AVAILABLE/UNAVAILABLE marker.  So, the&lt;br /&gt;#         memory looks like this&lt;br /&gt;#&lt;br /&gt;# #########################################################&lt;br /&gt;# #Available Marker#Size of memory#Actual memory locations#&lt;br /&gt;# #########################################################&lt;br /&gt;#                                  ^--Returned pointer&lt;br /&gt;#                                     points here&lt;br /&gt;#         The pointer we return only points to the actual&lt;br /&gt;#         locations requested to make it easier for the&lt;br /&gt;#         calling program. It also allows us to change our&lt;br /&gt;#         structure without the calling program having to&lt;br /&gt;#         change at all.&lt;br /&gt;&lt;br /&gt;.section .data&lt;a name="255"&gt;&lt;/a&gt;&lt;a name="IDX-158"&gt;&lt;/a&gt;&lt;br /&gt;#######GLOBAL VARIABLES########&lt;br /&gt;&lt;br /&gt;#This points to the beginning of the memory we are managing&lt;br /&gt;heap_begin:&lt;br /&gt;.long 0&lt;br /&gt;&lt;br /&gt;#This points to one location past the memory we are managing&lt;br /&gt;current_break:&lt;br /&gt;.long 0&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;######STRUCTURE INFORMATION####&lt;br /&gt;#size of space for memory region header&lt;br /&gt;.equ HEADER_SIZE, 8&lt;br /&gt;#Location of the "available" flag in the header&lt;br /&gt;.equ HDR_AVAIL_OFFSET, 0&lt;br /&gt;#Location of the size field in the header&lt;br /&gt;.equ HDR_SIZE_OFFSET, 4&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;###########CONSTANTS###########&lt;br /&gt;.equ UNAVAILABLE, 0 #This is the number we will use to mark&lt;br /&gt;                  #space that has been given out&lt;br /&gt;.equ AVAILABLE, 1   #This is the number we will use to mark&lt;br /&gt;                  #space that has been returned, and is&lt;br /&gt;                  #available for giving&lt;br /&gt;.equ SYS_BRK, 45    #system call number for the break&lt;br /&gt;                  #system call&lt;br /&gt;&lt;br /&gt;.equ LINUX_SYSCALL, 0x80 #make system calls easier to read&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;.section .text&lt;a name="256"&gt;&lt;/a&gt;&lt;a name="IDX-159"&gt;&lt;/a&gt;&lt;br /&gt;##########FUNCTIONS############&lt;br /&gt;&lt;br /&gt;##allocate_init##&lt;br /&gt;#PURPOSE: call this function to initialize the&lt;br /&gt;#         functions (specifically, this sets heap_begin and&lt;br /&gt;#         current_break).  This has no parameters and no&lt;br /&gt;#         return value.&lt;br /&gt;.globl allocate_init&lt;br /&gt;.type allocate_init, @function&lt;br /&gt;allocate_init:&lt;br /&gt;pushl %ebp                   #standard function stuff&lt;br /&gt;movl  %esp, %ebp&lt;br /&gt;&lt;br /&gt;#If the brk system call is called with 0 in %ebx, it&lt;br /&gt;#returns the last valid usable address&lt;br /&gt;movl  $SYS_BRK, %eax        #find out where the break is&lt;br /&gt;movl  $0, %ebx&lt;br /&gt;int   $LINUX_SYSCALL&lt;br /&gt;&lt;br /&gt;incl  %eax                  #%eax now has the last valid&lt;br /&gt;                         #address, and we want the&lt;br /&gt;                         #memory location after that&lt;br /&gt;&lt;br /&gt;movl  %eax, current_break   #store the current break&lt;br /&gt;&lt;br /&gt;movl  %eax, heap_begin      #store the current break as our&lt;br /&gt;                         #first address. This will cause&lt;br /&gt;                         #the allocate function to get&lt;br /&gt;                         #more memory from Linux the&lt;br /&gt;                         #first time it is run&lt;br /&gt;&lt;br /&gt;movl  %ebp, %esp            #exit the function&lt;br /&gt;popl  %ebp&lt;a name="257"&gt;&lt;/a&gt;&lt;a name="IDX-160"&gt;&lt;/a&gt;&lt;br /&gt;ret&lt;br /&gt;#####END OF FUNCTION#######&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;##allocate##&lt;br /&gt;#PURPOSE:    This function is used to grab a section of&lt;br /&gt;#            memory. It checks to see if there are any&lt;br /&gt;#            free blocks, and, if not, it asks Linux&lt;br /&gt;#            for a new one.&lt;br /&gt;#&lt;br /&gt;#PARAMETERS: This function has one parameter - the size&lt;br /&gt;#            of the memory block we want to allocate&lt;br /&gt;#&lt;br /&gt;#RETURN VALUE:&lt;br /&gt;#            This function returns the address of the&lt;br /&gt;#            allocated memory in %eax.  If there is no&lt;br /&gt;#            memory available, it will return 0 in %eax&lt;br /&gt;#&lt;br /&gt;######PROCESSING########&lt;br /&gt;#Variables used:&lt;br /&gt;#&lt;br /&gt;#   %ecx - hold the size of the requested memory&lt;br /&gt;#          (first/only parameter)&lt;br /&gt;#   %eax - current memory region being examined&lt;br /&gt;#   %ebx - current break position&lt;br /&gt;#   %edx - size of current memory region&lt;br /&gt;#&lt;br /&gt;#We scan through each memory region starting with&lt;br /&gt;#heap_begin. We look at the size of each one, and if&lt;br /&gt;#it has been allocated.  If it's big enough for the&lt;br /&gt;#requested size, and its available, it grabs that one.&lt;br /&gt;#If it does not find a region large enough, it asks&lt;br /&gt;#Linux for more memory.  In that case, it moves&lt;br /&gt;#current_break up&lt;a name="258"&gt;&lt;/a&gt;&lt;a name="IDX-161"&gt;&lt;/a&gt;&lt;br /&gt;.globl allocate&lt;br /&gt;.type allocate, @function&lt;br /&gt;.equ ST_MEM_SIZE,  8 #stack position of the memory size&lt;br /&gt;                  #to allocate&lt;br /&gt;allocate:&lt;br /&gt;pushl %ebp                   #standard function stuff&lt;br /&gt;movl  %esp, %ebp&lt;br /&gt;&lt;br /&gt;movl  ST_MEM_SIZE(%ebp), %ecx #%ecx will hold the size&lt;br /&gt;            #we are looking for (which is the first&lt;br /&gt;            #and only parameter)&lt;br /&gt;&lt;br /&gt;movl  heap_begin, %eax      #%eax will hold the current&lt;br /&gt;                         #search location&lt;br /&gt;&lt;br /&gt;movl  current_break, %ebx   #%ebx will hold the current&lt;br /&gt;                         #break&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;alloc_loop_begin:               #here we iterate through each&lt;br /&gt;                            #memory region&lt;br /&gt;&lt;br /&gt;cmpl  %ebx, %eax        #need more memory if these are equal&lt;br /&gt;je    move_break&lt;br /&gt;&lt;br /&gt;#grab the size of this memory&lt;br /&gt;movl  HDR_SIZE_OFFSET(%eax), %edx&lt;br /&gt;#If the space is unavailable, go to the&lt;br /&gt;cmpl  $UNAVAILABLE, HDR_AVAIL_OFFSET(%eax)&lt;br /&gt;je    next_location         #next one&lt;br /&gt;&lt;br /&gt;cmpl  %edx, %ecx     #If the space is available, compare&lt;br /&gt;jle   allocate_here  #the size to the needed size.  If its&lt;br /&gt;                  #big enough, go to allocate_here&lt;a name="259"&gt;&lt;/a&gt;&lt;a name="IDX-162"&gt;&lt;/a&gt;&lt;br /&gt;next_location:&lt;br /&gt;addl  $HEADER_SIZE, %eax #The total size of the memory&lt;br /&gt;addl  %edx, %eax         #region is the sum of the size&lt;br /&gt;                      #requested (currently stored&lt;br /&gt;                      #in %edx), plus another 8 bytes&lt;br /&gt;                      #for the header (4 for the&lt;br /&gt;                      #AVAILABLE/UNAVAILABLE flag,&lt;br /&gt;                      #and 4 for the size of the&lt;br /&gt;                      #region). So, adding %edx and $8&lt;br /&gt;                      #to %eax will get the address&lt;br /&gt;                      #of the next memory region&lt;br /&gt;&lt;br /&gt;jmp   alloc_loop_begin      #go look at the next location&lt;br /&gt;&lt;br /&gt;allocate_here:                      #if we've made it here,&lt;br /&gt;                                #that means that the&lt;br /&gt;                         #region header of the region&lt;br /&gt;                         #to allocate is in %eax&lt;br /&gt;&lt;br /&gt;#mark space as unavailable&lt;br /&gt;movl  $UNAVAILABLE, HDR_AVAIL_OFFSET(%eax)&lt;br /&gt;addl  $HEADER_SIZE, %eax    #move %eax past the header to&lt;br /&gt;                         #the usable memory (since&lt;br /&gt;                         #that's what we return)&lt;br /&gt;&lt;br /&gt;movl  %ebp, %esp            #return from the function&lt;br /&gt;popl  %ebp&lt;br /&gt;ret&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;move_break:                      #if we've made it here, that&lt;br /&gt;                             #means that we have exhausted&lt;br /&gt;                             #all addressable memory, and&lt;br /&gt;                             #we need to ask for more.&lt;br /&gt;                      #%ebx holds the current&lt;a name="260"&gt;&lt;/a&gt;&lt;a name="IDX-163"&gt;&lt;/a&gt;&lt;br /&gt;                      #endpoint of the data,&lt;br /&gt;                             #and %ecx holds its size&lt;br /&gt;&lt;br /&gt;                      #we need to increase %ebx to&lt;br /&gt;                      #where we _want_ memory&lt;br /&gt;                      #to end, so we&lt;br /&gt;addl  $HEADER_SIZE, %ebx #add space for the headers&lt;br /&gt;                      #structure&lt;br /&gt;addl  %ecx, %ebx         #add space to the break for&lt;br /&gt;                      #the data requested&lt;br /&gt;&lt;br /&gt;                      #now its time to ask Linux&lt;br /&gt;                      #for more memory&lt;br /&gt;&lt;br /&gt;pushl %eax               #save needed registers&lt;br /&gt;pushl %ecx&lt;br /&gt;pushl %ebx&lt;br /&gt;&lt;br /&gt;movl  $SYS_BRK, %eax     #reset the break (%ebx has&lt;br /&gt;                      #the requested break point)&lt;br /&gt;int   $LINUX_SYSCALL&lt;br /&gt;            #under normal conditions, this should&lt;br /&gt;            #return the new break in %eax, which&lt;br /&gt;            #will be either 0 if it fails, or&lt;br /&gt;            #it will be equal to or larger than&lt;br /&gt;            #we asked for.  We don't care&lt;br /&gt;            #in this program where it actually&lt;br /&gt;            #sets the break, so as long as %eax&lt;br /&gt;            #isn't 0, we don't care what it is&lt;br /&gt;&lt;br /&gt;cmpl  $0, %eax           #check for error conditions&lt;br /&gt;je    error&lt;br /&gt;&lt;br /&gt;popl  %ebx               #restore saved registers&lt;br /&gt;popl  %ecx&lt;a name="261"&gt;&lt;/a&gt;&lt;a name="IDX-164"&gt;&lt;/a&gt;&lt;br /&gt;popl  %eax&lt;br /&gt;&lt;br /&gt;#set this memory as unavailable, since we're about to&lt;br /&gt;#give it away&lt;br /&gt;movl  $UNAVAILABLE, HDR_AVAIL_OFFSET(%eax)&lt;br /&gt;#set the size of the memory&lt;br /&gt;movl  %ecx, HDR_SIZE_OFFSET(%eax)&lt;br /&gt;&lt;br /&gt;#move %eax to the actual start of usable memory.&lt;br /&gt;#%eax now holds the return value&lt;br /&gt;addl  $HEADER_SIZE, %eax&lt;br /&gt;&lt;br /&gt;movl  %ebx, current_break   #save the new break&lt;br /&gt;&lt;br /&gt;movl  %ebp, %esp            #return the function&lt;br /&gt;popl  %ebp&lt;br /&gt;ret&lt;br /&gt;&lt;br /&gt;error:&lt;br /&gt;movl  $0, %eax              #on error, we return zero&lt;br /&gt;movl  %ebp, %esp&lt;br /&gt;popl  %ebp&lt;br /&gt;ret&lt;br /&gt;########END OF FUNCTION########&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;##deallocate##&lt;br /&gt;#PURPOSE:&lt;br /&gt;#    The purpose of this function is to give back&lt;br /&gt;#    a region of memory to the pool after we're done&lt;br /&gt;#    using it.&lt;br /&gt;#&lt;br /&gt;#PARAMETERS:&lt;br /&gt;#    The only parameter is the address of the memory&lt;br /&gt;#    we want to return to the memory pool.&lt;a name="262"&gt;&lt;/a&gt;&lt;a name="IDX-165"&gt;&lt;/a&gt;&lt;br /&gt;#&lt;br /&gt;#RETURN VALUE:&lt;br /&gt;#    There is no return value&lt;br /&gt;#PROCESSING:&lt;br /&gt;#    If you remember, we actually hand the program the&lt;br /&gt;#    start of the memory that they can use, which is&lt;br /&gt;#    8 storage locations after the actual start of the&lt;br /&gt;#    memory region.  All we have to do is go back&lt;br /&gt;#    8 locations and mark that memory as available,&lt;br /&gt;#    so that the allocate function knows it can use it.&lt;br /&gt;.globl deallocate&lt;br /&gt;.type deallocate, @function&lt;br /&gt;#stack position of the memory region to free&lt;br /&gt;.equ ST_MEMORY_SEG, 4&lt;br /&gt;deallocate:&lt;br /&gt;#since the function is so simple, we&lt;br /&gt;#don't need any of the fancy function stuff&lt;br /&gt;&lt;br /&gt;#get the address of the memory to free&lt;br /&gt;#(normally this is 8(%ebp), but since&lt;br /&gt;#we didn't push %ebp or move %esp to&lt;br /&gt;#%ebp, we can just do 4(%esp)&lt;br /&gt;movl  ST_MEMORY_SEG(%esp), %eax&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;#get the pointer to the real beginning of the memory&lt;br /&gt;subl  $HEADER_SIZE, %eax&lt;br /&gt;&lt;br /&gt;#mark it as available&lt;br /&gt;movl  $AVAILABLE, HDR_AVAIL_OFFSET(%eax)&lt;br /&gt;&lt;br /&gt;#return&lt;br /&gt;ret&lt;br /&gt;########END OF FUNCTION##########&lt;br /&gt;&lt;a name="263"&gt;&lt;/a&gt;&lt;a name="IDX-166"&gt;&lt;/a&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;The first thing to notice is that there is no &lt;span class="fixed"&gt;_start&lt;/span&gt; symbol. The reason is that this is just a set of  functions. A memory manager by itself is not a full program - it doesn't do  anything. It is simply a utility to be used by other programs.&lt;/p&gt; &lt;p class="para"&gt;To assemble the program, do the following:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;as alloc.s -o alloc.o&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;Okay, now let's look at the code.&lt;/p&gt; &lt;div class="section"&gt; &lt;h3 class="sect3-title"&gt;&lt;a name="264"&gt;&lt;/a&gt;&lt;a name="ch09lev2sec1"&gt;&lt;/a&gt;Variables and  Constants&lt;/h3&gt; &lt;p class="first-para"&gt;At the beginning of the program, we have two locations set  up:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;heap_begin:&lt;br /&gt;.long 0&lt;br /&gt;&lt;br /&gt;current_break:&lt;br /&gt;.long 0&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;Remember, the section of memory being managed is commonly referred  to as the &lt;i class="emphasis"&gt;heap.&lt;/i&gt; When we assemble the program, we have no  idea where the beginning of the heap is, nor where the current break is.  Therefore, we reserve space for their addresses, but just fill them with a 0 for  the time being.&lt;/p&gt; &lt;p class="para"&gt;Next we have a set of constants to define the structure of the  heap. The way this memory manager works is that before each region of memory  allocated, we will have a short record describing the memory. This record has a  word reserved for the available flag and a word for the region's size. The  actual memory allocated immediately follows this record. The available flag is  used to mark whether this region is available for allocations, or if it is  currently in use. The size field lets us know both whether or not this region is  big enough for an allocation request, as &lt;a name="265"&gt;&lt;/a&gt;&lt;a name="IDX-167"&gt;&lt;/a&gt;well as the location of the next memory region. The following  constants describe this record:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt; .equ HEADER_SIZE, 8&lt;br /&gt;.equ HDR_AVAIL_OFFSET, 0&lt;br /&gt;.equ HDR_SIZE_OFFSET, 4&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;This says that the header is 8 bytes total, the available flag is  offset 0 bytes from the beginning, and the size field is offset 4 bytes from the  beginning. If we are careful to always use these constants, then we protect  ourselves from having to do too much work if we later decide to add more  information to the header.&lt;/p&gt; &lt;p class="para"&gt;The values that we will use for our &lt;span class="fixed"&gt;available&lt;/span&gt; field are either 0 for unavailable, or 1 for  available. To make this easier to read, we have the following definitions:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt; .equ UNAVAILABLE, 0&lt;br /&gt;.equ AVAILABLE, 1&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;Finally, we have our Linux system call definitions:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt; .equ BRK, 45&lt;br /&gt;.equ LINUX_SYSCALL, 0x80&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt; &lt;div class="section"&gt; &lt;h3 class="sect3-title"&gt;&lt;a name="266"&gt;&lt;/a&gt;&lt;a name="ch09lev2sec2"&gt;&lt;/a&gt;The &lt;span class="fixed"&gt;allocate_init&lt;/span&gt; Function&lt;/h3&gt; &lt;p class="first-para"&gt;Okay, this is a simple function. All it does is set up the  &lt;span class="fixed"&gt;heap_begin&lt;/span&gt; and &lt;span class="fixed"&gt;current_break&lt;/span&gt;  variables we discussed earlier. So, if you remember the discussion earlier, the  current break can be found using the &lt;span class="fixed"&gt;brk&lt;/span&gt; system call.  So, the function starts like this:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt; pushl %ebp&lt;br /&gt;movl  %esp, %ebp&lt;br /&gt;&lt;br /&gt;movl  $SYS_BRK, %eax&lt;a name="267"&gt;&lt;/a&gt;&lt;a name="IDX-168"&gt;&lt;/a&gt;&lt;br /&gt;movl  $0, %ebx&lt;br /&gt;int   $LINUX_SYSCALL&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;Anyway, after &lt;span class="fixed"&gt;int $LINUX_SYSCALL, %eax&lt;/span&gt;  holds the last valid address. We actually want the first invalid address instead  of the last valid address, so we just increment &lt;span class="fixed"&gt;%eax&lt;/span&gt;.  Then we move that value to the &lt;span class="fixed"&gt;heap_begin&lt;/span&gt; and &lt;span class="fixed"&gt;current_break&lt;/span&gt; locations. Then we leave the function. The code  looks like this:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt; incl  %eax&lt;br /&gt;movl  %eax, current_break&lt;br /&gt;movl  %eax, heap_begin&lt;br /&gt;movl  %ebp, %esp&lt;br /&gt;popl  %ebp&lt;br /&gt;ret&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="last-para"&gt;The heap consists of the memory between &lt;span class="fixed"&gt;heap_begin&lt;/span&gt; and &lt;span class="fixed"&gt;current_break,&lt;/span&gt; so  this says that we start off with a heap of zero bytes. Our &lt;span class="fixed"&gt;allocate&lt;/span&gt; function will then extend the heap as much as it  needs to when it is called.&lt;/p&gt;&lt;/div&gt; &lt;div class="section"&gt; &lt;h3 class="sect3-title"&gt;&lt;a name="268"&gt;&lt;/a&gt;&lt;a name="ch09lev2sec3"&gt;&lt;/a&gt;The &lt;span class="fixed"&gt;allocate&lt;/span&gt; Function&lt;/h3&gt; &lt;p class="first-para"&gt;This is the doozy function. Let's start by looking at an  outline of the function:&lt;/p&gt; &lt;ol class="orderedlist"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;Start at the beginning of the heap.&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;Check to see if we're at the end of the heap.&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;If we are at the end of the heap, grab the memory we need  from Linux, mark it as "unavailable" and return it. If Linux won't give us any  more, return a 0.&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;If the current memory region is marked "unavailable", go to  the next one, and go back to step 2.&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;If the current memory region is too small to hold the  requested amount of space, go back to step 2.&lt;/p&gt;&lt;a name="269"&gt;&lt;/a&gt;&lt;a name="IDX-169"&gt;&lt;/a&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;If the memory region is available and large enough, mark it  as "unavailable" and return it.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt; &lt;p class="para"&gt;Now, look back through the code with this in mind. Be sure to read  the comments so you'll know which register holds which value.&lt;/p&gt; &lt;p class="para"&gt;Now that you've looked back through the code, let's examine it one  line at a time. We start off like this:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt; pushl %ebp&lt;br /&gt;movl  %esp, %ebp&lt;br /&gt;movl  ST_MEM_SIZE(%ebp), %ecx&lt;br /&gt;movl  heap_begin, %eax&lt;br /&gt;movl  current_break, %ebx&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;This part initializes all of our registers. The first two lines  are standard function stuff. The next move pulls the size of the memory to  allocate off of the stack. This is our only function parameter. After that, it  moves the beginning heap address and the end of the heap into registers. I am  now ready to do processing.&lt;/p&gt; &lt;p class="para"&gt;The &lt;a class="internaljump" href="http://www2.blogger.com/post-edit.g?blogID=8901974503278002812&amp;postID=3284968477063416573#ch09lev2sec4"&gt;next section&lt;/a&gt; is  marked &lt;span class="fixed"&gt;alloc_loop_begin&lt;/span&gt;. In this loop we are going to  examine memory regions until we either find an open memory region or determine  that we need more memory. Our first instructions check to see if we need more  memory:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt; cmpl %ebx, %eax&lt;br /&gt;je   move_break&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;&lt;span class="fixed"&gt;%eax&lt;/span&gt; holds the current memory region  being examined and &lt;span class="fixed"&gt;%ebx&lt;/span&gt; holds the location past the end  of the heap. Therefore if the next region to be examined is past the end of the  heap, it means we need more memory to allocate a region of this size. Let's skip  down to &lt;span class="fixed"&gt;move_break&lt;/span&gt; and see what happens there:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;move_break:&lt;br /&gt;addl  $HEADER_SIZE, %ebx&lt;br /&gt;addl  %ecx, %ebx&lt;a name="270"&gt;&lt;/a&gt;&lt;a name="IDX-170"&gt;&lt;/a&gt;&lt;br /&gt;pushl %eax&lt;br /&gt;pushl %ecx&lt;br /&gt;pushl %ebx&lt;br /&gt;movl  $SYS_BRK, %eax&lt;br /&gt;int   $LINUX_SYSCALL&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;When we reach this point in the code, &lt;span class="fixed"&gt;%ebx&lt;/span&gt; holds where we want the next region of memory to be. So,  we add our header size and region size to &lt;span class="fixed"&gt;%ebx&lt;/span&gt;, and  that's where we want the system break to be. We then push all the registers we  want to save on the stack, and call the &lt;span class="fixed"&gt;brk&lt;/span&gt; system  call. After that we check for errors:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt; cmpl  $0, %eax&lt;br /&gt;je    error&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;If there were no errors we pop the registers back off the stack,  mark the memory as unavailable, record the size of the memory, and make sure  &lt;span class="fixed"&gt;%eax&lt;/span&gt; points to the start of usable memory (which is &lt;i class="emphasis"&gt;after&lt;/i&gt; the header).&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt; popl  %ebx&lt;br /&gt;popl  %ecx&lt;br /&gt;popl  %eax&lt;br /&gt;movl  $UNAVAILABLE, HDR_AVAIL_OFFSET(%eax)&lt;br /&gt;movl  %ecx, HDR_SIZE_OFFSET(%eax)&lt;br /&gt;addl  $HEADER_SIZE, %eax&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;Then we store the new program break and return the pointer to the  allocated memory.&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt; movl  %ebx, current_break&lt;br /&gt;movl  %ebp, %esp&lt;br /&gt;popl  %ebp&lt;br /&gt;ret&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;The &lt;span class="fixed"&gt;error&lt;/span&gt; code just returns 0 in &lt;span class="fixed"&gt;%eax&lt;/span&gt;, so we won't discuss it.&lt;/p&gt;&lt;a name="271"&gt;&lt;/a&gt;&lt;a name="IDX-171"&gt;&lt;/a&gt; &lt;p class="para"&gt;Let's go back look at the rest of the loop. What happens if the  current memory being looked at isn't past the end of the heap? Well, let's  look.&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt; movl HDR_SIZE_OFFSET(%eax), %edx&lt;br /&gt;cmpl $UNAVAILABLE, HDR_AVAIL_OFFSET(%eax)&lt;br /&gt;je   next_location&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;This first grabs the size of the memory region and puts it in  &lt;span class="fixed"&gt;%edx&lt;/span&gt;. Then it looks at the available flag to see if it  is set to &lt;span class="fixed"&gt;UNAVAILABLE&lt;/span&gt;. If so, that means that memory  region is in use, so we'll have to skip over it. So, if the available flag is  set to &lt;span class="fixed"&gt;UNAVAILABLE&lt;/span&gt;, you go to the code labeled &lt;span class="fixed"&gt;next_location&lt;/span&gt;. If the available flag is set to &lt;span class="fixed"&gt;AVAILABLE&lt;/span&gt;, then we keep on going.&lt;/p&gt; &lt;p class="para"&gt;Let's say that the space was available, and so we keep going. Then  we check to see if this space is big enough to hold the requested amount of  memory. The size of this region is being held in &lt;span class="fixed"&gt;%edx&lt;/span&gt;,  so we do this:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt; cmpl  %edx, %ecx&lt;br /&gt;jle   allocate_here&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;If the requested size is less than or equal to the current  region's size, we can use this block. It doesn't matter if the current region is  larger than requested, because the extra space will just be unused. So, let's  jump down to &lt;span class="fixed"&gt;allocate_here&lt;/span&gt; and see what happens:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt; movl  $UNAVAILABLE, HDR_AVAIL_OFFSET(%eax)&lt;br /&gt;addl  $HEADER_SIZE, %eax&lt;br /&gt;movl  %ebp, %esp&lt;br /&gt;popl  %ebp&lt;br /&gt;ret&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;It marks the memory as being unavailable. Then it moves the  pointer &lt;span class="fixed"&gt;%eax&lt;/span&gt; past the header, and uses it as the return  value for the function. Remember, the person using this function doesn't need to  even know about our memory header record. They just need a pointer to usable  memory.&lt;/p&gt;&lt;a name="272"&gt;&lt;/a&gt;&lt;a name="IDX-172"&gt;&lt;/a&gt; &lt;p class="para"&gt;Okay, so let's say the region wasn't big enough. What then? Well,  we would then be at the code labeled &lt;span class="fixed"&gt;next_location&lt;/span&gt;.  This section of code is used any time that we figure out that the current memory  region won't work for allocating memory. All it does is advance &lt;span class="fixed"&gt;%eax&lt;/span&gt; to the next possible memory region, and goes back to the  beginning of the loop. Remember that &lt;span class="fixed"&gt;%edx&lt;/span&gt; is holding  the size of the current memory region, and &lt;span class="fixed"&gt;HEADER_SIZE  &lt;/span&gt;is the symbol for the size of the memory region's header. So this code  will move us to the next memory region:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt; addl  $HEADER_SIZE, %eax&lt;br /&gt;addl  %edx, %eax&lt;br /&gt;jmp   alloc_loop_begin&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;And now the function runs another loop.&lt;/p&gt; &lt;p class="para"&gt;Whenever you have a loop, you must make sure that it will &lt;i class="emphasis"&gt;always&lt;/i&gt; end. The best way to do that is to examine all of the  possibilities, and make sure that all of them eventually lead to the loop  ending. In our case, we have the following possibilities:&lt;/p&gt; &lt;ul class="itemizedlist"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;We will reach the end of the heap&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;We will find a memory region that's available and large  enough&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;We will go to the next location&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p class="last-para"&gt;The first two items are conditions that will cause the loop  to end. The third one will keep it going. However, even if we never find an open  region, we will eventually reach the end of the heap, because it is a finite  size. Therefore, we know that no matter which condition is true, the loop has to  eventually hit a terminating condition.&lt;/p&gt;&lt;/div&gt; &lt;div class="section"&gt; &lt;h3 class="sect3-title"&gt;&lt;a name="273"&gt;&lt;/a&gt;&lt;a name="ch09lev2sec4"&gt;&lt;/a&gt;The &lt;span class="fixed"&gt;deallocate&lt;/span&gt; Function&lt;/h3&gt; &lt;p class="first-para"&gt;The &lt;span class="fixed"&gt;deallocate&lt;/span&gt; function is much  easier than the &lt;span class="fixed"&gt;allocate&lt;/span&gt; one. That's because it doesn't  have to do any searching at all. It can just mark the current memory &lt;a name="274"&gt;&lt;/a&gt;&lt;a name="IDX-173"&gt;&lt;/a&gt;region as &lt;span class="fixed"&gt;AVAILABLE&lt;/span&gt;,  and &lt;span class="fixed"&gt;allocate&lt;/span&gt; will find it next time it is called. So we  have:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt; movl  ST_MEMORY_SEG(%esp), %eax&lt;br /&gt;subl  $HEADER_SIZE, %eax&lt;br /&gt;movl  $AVAILABLE, HDR_AVAIL_OFFSET(%eax)&lt;br /&gt;ret&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="last-para"&gt;In this function, we don't have to save &lt;span class="fixed"&gt;%ebp&lt;/span&gt; or &lt;span class="fixed"&gt;%esp&lt;/span&gt; since we're not  changing them, nor do we have to restore them at the end. All we're doing is  reading the address of the memory region from the stack, backing up to the  beginning of the header, and marking the region as available. This function has  no return value, so we don't care what we leave in &lt;span class="fixed"&gt;%eax&lt;/span&gt;.&lt;/p&gt;&lt;/div&gt; &lt;div class="section"&gt; &lt;h3 class="sect3-title"&gt;&lt;a name="275"&gt;&lt;/a&gt;&lt;a name="ch09lev2sec5"&gt;&lt;/a&gt;Performance  Issues and Other Problems&lt;/h3&gt; &lt;p class="first-para"&gt;Our simplistic memory manager is not really useful for  anything more than an academic exercise. This section looks at the problems with  such a simplistic allocator.&lt;/p&gt; &lt;p class="para"&gt;The biggest problem here is speed. Now, if there are only a few  allocations made, then speed won't be a big issue. But think about what happens  if you make a thousand allocations. On allocation number 1000, you have to  search through 999 memory regions to find that you have to request more memory.  As you can see, that's getting pretty slow. In addition, remember that Linux can  keep pages of memory on disk instead of in memory. So, since you have to go  through every piece of memory your program's memory, that means that Linux has  to load every part of memory that's currently on disk to check to see if it is  available. You can see how this could get really, really slow. &lt;sup&gt;[&lt;a href="http://www2.blogger.com/post-edit.g?blogID=8901974503278002812&amp;amp;postID=3284968477063416573#ftn.N505" name="N505"&gt;6&lt;/a&gt;]&lt;/sup&gt; This method is said to run in &lt;i class="emphasis"&gt;linear&lt;/i&gt; time, which means that every element you have to  manage makes your program &lt;a name="276"&gt;&lt;/a&gt;&lt;a name="IDX-174"&gt;&lt;/a&gt;take longer. A  program that runs in &lt;i class="emphasis"&gt;constant&lt;/i&gt; time takes the same amount  of time no matter how many elements you are managing. Take the &lt;span class="fixed"&gt;deallocate&lt;/span&gt; function, for instance. It only runs 4  instructions, no matter how many elements we are managing, or where they are in  memory. In fact, although our &lt;span class="fixed"&gt;allocate&lt;/span&gt; function is one  of the slowest of all memory managers, the &lt;span class="fixed"&gt;deallocate&lt;/span&gt;  function is one of the fastest.&lt;/p&gt; &lt;p class="para"&gt;Another performance problem is the number of times we're calling  the &lt;span class="fixed"&gt;brk&lt;/span&gt; system call. System calls take a long time.  They aren't like functions, because the processor has to switch modes. Your  program isn't allowed to map itself memory, but the Linux kernel is. So, the  processor has to switch into &lt;i class="emphasis"&gt;kernel mode,&lt;/i&gt; then Linux maps  the memory, and then switches back to &lt;i class="emphasis"&gt;user mode&lt;/i&gt; for your  application to continue running. This is also called a &lt;i class="emphasis"&gt;context  switch.&lt;/i&gt; Context switches are relatively slow on x86 processors. Generally,  you should avoid calling the kernel unless you really need to.&lt;/p&gt; &lt;p class="para"&gt;Another problem that we have is that we aren't recording where  Linux actually sets the break. Previously we mentioned that Linux might actually  set the break past where we requested it. In this program, we don't even look at  where Linux actually sets the break - we just assume it sets it where we  requested. That's not really a bug, but it will lead to unnecessary &lt;span class="fixed"&gt;brk&lt;/span&gt; system calls when we already have the memory mapped  in.&lt;/p&gt; &lt;p class="last-para"&gt;Another problem we have is that if we are looking for a  5-byte region of memory, and the first open one we come to is 1000 bytes, we  will simply mark the whole thing as allocated and return it. This leaves 995  bytes of unused, but allocated, memory. It would be nice in such situations to  break it apart so the other 995 bytes can be used later. It would also be nice  to combine consecutive free spaces when looking for large  allocations.&lt;/p&gt;&lt;/div&gt;&lt;/div&gt; &lt;div class="footnotes"&gt; &lt;div class="footnote"&gt; &lt;p&gt;&lt;sup&gt;[&lt;a href="http://www2.blogger.com/post-edit.g?blogID=8901974503278002812&amp;amp;postID=3284968477063416573#N505" name="ftn.N505"&gt;6&lt;/a&gt;]&lt;/sup&gt;This is why adding more  memory to your computer makes it run faster. The more memory your computer has,  the less it puts on disk, so it doesn't have to always be interrupting your  programs to retreive pages off the disk.&lt;/p&gt;&lt;div class="section"&gt; &lt;h2 class="first-section-title"&gt;&lt;a name="277"&gt;&lt;/a&gt;&lt;a name="ch09lev1sec6"&gt;&lt;/a&gt;Using Our  Allocator&lt;/h2&gt;&lt;a name="278"&gt;&lt;/a&gt;&lt;a name="IDX-175"&gt;&lt;/a&gt; &lt;p class="para"&gt;The programs we do in this book aren't complicated enough to  necessitate a memory manager. Therefore, we will just use our memory manager to  allocate a buffer for one of our file reading/writing programs instead of  assigning it in the &lt;span class="fixed"&gt;.bss&lt;/span&gt;.&lt;/p&gt; &lt;p class="para"&gt;The program we will demonstrate this on is &lt;span class="fixed"&gt;read-records.s&lt;/span&gt; from &lt;span class="chapterjump"&gt;Chapter 6&lt;/span&gt;. This program uses a buffer  named &lt;span class="fixed"&gt;record_buffer&lt;/span&gt; to handle its input/output needs.  We will simply change this from being a buffer defined in .&lt;span class="fixed"&gt;bss&lt;/span&gt; to being a pointer to a dynamically-allocated buffer  using our memory manager. You will need to have the code from that program handy  as we will only be discussing the changes in this section.&lt;/p&gt; &lt;p class="para"&gt;The first change we need to make is in the declaration. Currently  it looks like this:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt; .section .bss&lt;br /&gt;.lcomm, record_buffer, RECORD_SIZE&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;It would be a misnomer to keep the same name, since we are  switching it from being an actual buffer to being a pointer to a buffer. In  addition, it now only needs to be one word big (enough to hold a pointer). The  new declaration will stay in the &lt;span class="fixed"&gt;.data&lt;/span&gt; section and look  like this:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;record_buffer_ptr:&lt;br /&gt;.long 0&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;Our next change is we need to initialize our memory manager  immediately after we start our program. Therefore, right after the stack is set  up, the following call needs to be added:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt; call allocate_init&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;After that, the memory manager is ready to start servicing memory  allocation requests. We need to allocate enough memory to hold these records  that we are &lt;a name="279"&gt;&lt;/a&gt;&lt;a name="IDX-176"&gt;&lt;/a&gt;reading. Therefore, we will call  &lt;span class="fixed"&gt;allocate&lt;/span&gt; to allocate this memory, and then save the  pointer it returns into &lt;span class="fixed"&gt;record_buffer_ptr&lt;/span&gt;. Like  this:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt; pushl $RECORD_SIZE&lt;br /&gt;call  allocate&lt;br /&gt;movl  %eax, record_buffer_ptr&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;Now, when we make the call to &lt;span class="fixed"&gt;read_record&lt;/span&gt;, it is expecting a pointer. In the old code, the  pointer was the immediate-mode reference to &lt;span class="fixed"&gt;record_buffer&lt;/span&gt;. Now, &lt;span class="fixed"&gt;record_buffer_ptr&lt;/span&gt; just holds the pointer rather than the  buffer itself. Therefore, we must do a direct mode load to get the value in  &lt;span class="fixed"&gt;record_buffer_ptr&lt;/span&gt;. We need to remove this line:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;pushl $record_buffer&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;And put this line in its place:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;pushl record_buffer_ptr&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;The next change comes when we are trying to find the address of  the firstname field of our record. In the old code, it was &lt;span class="fixed"&gt;$RECORD_FIRSTNAME + record_buffer&lt;/span&gt;. However, that only works  because it is a constant offset from a constant address. In the new code, it is  the offset of an address stored in &lt;span class="fixed"&gt;record_buffer_ptr&lt;/span&gt;.  To get that value, we will need to move the pointer into a register, and then  add &lt;span class="fixed"&gt;$RECORD_FIRSTNAME&lt;/span&gt; to it to get the pointer. So  where we have the following code:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt; pushl $RECORD_FIRSTNAME + record_buffer&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;We need to replace it with this:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt; movl  record_buffer_ptr, %eax&lt;br /&gt;addl  $RECORD_FIRSTNAME, %eax&lt;br /&gt;pushl %eax&lt;br /&gt;&lt;a name="280"&gt;&lt;/a&gt;&lt;a name="IDX-177"&gt;&lt;/a&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;Similarly, we need to change the line that says&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt; movl  $RECORD_FIRSTNAME + record_buffer, %ecx&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;so that it reads like this:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt; movl  record_buffer_ptr, %ecx&lt;br /&gt;addl  $RECORD_FIRSTNAME, %ecx&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;Finally, one change that we need to make is to deallocate the  memory once we are done with it (in this program it's not necessary, but it's a  good practice anyway). To do that, we just send &lt;span class="fixed"&gt;record_buffer_ptr&lt;/span&gt; to the &lt;span class="fixed"&gt;deallocate&lt;/span&gt;  function right before exitting:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt; pushl record_buffer_ptr&lt;br /&gt;call  deallocate&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;Now you can build your program with the following commands:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;as read-records.s -o read-records.o&lt;br /&gt;ld alloc.o read-record.o read-records.o write-newline.o count-&lt;br /&gt;chars.o -o read-records&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;You can then run your program by doing &lt;span class="fixed"&gt;./read-records.&lt;/span&gt; &lt;/p&gt; &lt;p class="last-para"&gt;The uses of dynamic memory allocation may not be apparent to  you at this point, but as you go from academic exercises to real-life programs  you will use it continually.&lt;/p&gt;&lt;h2 class="first-section-title"&gt;&lt;a name="281"&gt;&lt;/a&gt;&lt;a name="ch09lev1sec7"&gt;&lt;/a&gt;More  Information&lt;/h2&gt; &lt;p class="first-para"&gt;More information on memory handling in Linux and other  operating systems can be found at the following locations:&lt;/p&gt;&lt;a name="282"&gt;&lt;/a&gt;&lt;a name="IDX-178"&gt;&lt;/a&gt; &lt;ul class="itemizedlist"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;More information about the memory layout of Linux programs  can be found in Konstantin Boldyshev's document, "Startup state of a Linux/i386  ELF binary", available at &lt;a class="url" href="http://linuxassembly.org/startup.html" target="_top"&gt;http://linuxassembly.org/startup.html&lt;/a&gt; &lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;A good overview of virtual memory in many different systems  is available at &lt;a class="url" href="http://cne.gmu.edu/modules/vm/" target="_top"&gt;http://cne.gmu.edu/modules/vm/&lt;/a&gt; &lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;Several in-depth articles on Linux's virtual memory  subsystem is available at &lt;a class="url" href="http://www.nongnu.org/lkdp/files.html" target="_top"&gt;http://www.nongnu.org/lkdp/files.html&lt;/a&gt; &lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;Doug Lea has written up a description of his popular memory  allocator at &lt;a class="url" href="http://gee.cs.oswego.edu/dl/html/malloc.html" target="_top"&gt;http://gee.cs.oswego.edu/dl/html/malloc.html&lt;/a&gt; &lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;A paper on the 4.4 BSD memory allocator is available at &lt;a class="url" href="http://docs.freebsd.org/44doc/papers/malloc.html" target="_top"&gt;http://docs.freebsd.org/44doc/papers/malloc.html&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;div class="section"&gt; &lt;h2 class="first-section-title"&gt;&lt;a name="283"&gt;&lt;/a&gt;&lt;a name="ch09lev1sec8"&gt;&lt;/a&gt;Review&lt;/h2&gt; &lt;div class="section"&gt; &lt;h3 class="sect3-title"&gt;&lt;a name="284"&gt;&lt;/a&gt;&lt;a name="ch09lev2sec6"&gt;&lt;/a&gt;Know the  Concepts&lt;/h3&gt; &lt;ul class="itemizedlist"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;Describe the layout of memory when a Linux program  starts.&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;What is the heap?&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;What is the current break?&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;Which direction does the stack grow in?&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;Which direction does the heap grow in?&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;What happens when you access unmapped memory?&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;How does the operating system prevent processes from writing  over each other's memory?&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;Describe the process that occurs if a piece of memory you  are using is currently residing on disk?&lt;/p&gt;&lt;a name="285"&gt;&lt;/a&gt;&lt;a name="IDX-179"&gt;&lt;/a&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;Why do you need an allocator?&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt; &lt;div class="section"&gt; &lt;h3 class="sect3-title"&gt;&lt;a name="286"&gt;&lt;/a&gt;&lt;a name="ch09lev2sec7"&gt;&lt;/a&gt;Use the  Concepts&lt;/h3&gt; &lt;ul class="itemizedlist"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;Modify the memory manager so that it calls &lt;span class="fixed"&gt;allocate_init&lt;/span&gt; automatically if it hasn't been  initialized.&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;Modify the memory manager so that if the requested size of  memory is smaller than the region chosen, it will break up the region into  multiple parts. Be sure to take into account the size of the new header record  when you do this.&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;Modify one of your programs that uses buffers to use the  memory manager to get buffer memory rather than using the &lt;span class="fixed"&gt;.bss&lt;/span&gt;.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt; &lt;div class="section"&gt; &lt;h3 class="sect3-title"&gt;&lt;a name="287"&gt;&lt;/a&gt;&lt;a name="ch09lev2sec8"&gt;&lt;/a&gt;Going  Further&lt;/h3&gt; &lt;ul class="itemizedlist"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;Research &lt;i class="emphasis"&gt;garbage collection.&lt;/i&gt; What  advantages and disadvantages does this have over the style of memory management  used here?&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;Research &lt;i class="emphasis"&gt;reference counting.&lt;/i&gt; What  advantages and disadvantages does this have over the style of memory management  used here?&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;Change the name of the functions to &lt;span class="fixed"&gt;malloc&lt;/span&gt; and &lt;span class="fixed"&gt;free&lt;/span&gt;, and build them into  a shared library. Use &lt;span class="fixed"&gt;LD_PRELOAD&lt;/span&gt; to force them to be  used as your memory manager instead of the default one. Add some &lt;span class="fixed"&gt;write&lt;/span&gt; system calls to STDOUT to verify that your memory  manager is being used instead of the default one.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;a name="288"&gt;&lt;/a&gt;&lt;a name="IDX-180"&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8901974503278002812-3284968477063416573?l=programminggroundup.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://programminggroundup.blogspot.com/feeds/3284968477063416573/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8901974503278002812&amp;postID=3284968477063416573' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8901974503278002812/posts/default/3284968477063416573'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8901974503278002812/posts/default/3284968477063416573'/><link rel='alternate' type='text/html' href='http://programminggroundup.blogspot.com/2007/01/chapter-9-intermediate-memory-topics.html' title='Chapter 9: Intermediate Memory Topics'/><author><name>Admin</name><uri>http://www.blogger.com/profile/13783659974416042562</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_pYXuXAWhUJk/RcF0u5B51sI/AAAAAAAAABo/mZeE9f08GIA/s72-c/Fig03.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8901974503278002812.post-2114339705057527230</id><published>2007-01-31T18:22:00.000-08:00</published><updated>2007-01-31T20:20:50.276-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='code libraries'/><category scheme='http://www.blogger.com/atom/ns#' term='x86'/><category scheme='http://www.blogger.com/atom/ns#' term='asm'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='assembly language'/><title type='text'>Chapter 8: Sharing Functions with Code Libraries</title><content type='html'>&lt;div class="section"&gt; &lt;h2 class="sect2-title"&gt;&lt;a name="209"&gt;&lt;/a&gt;Overview&lt;/h2&gt;&lt;a name="210"&gt;&lt;/a&gt;&lt;a name="IDX-129"&gt;&lt;/a&gt; &lt;p class="para"&gt;By now you should realize that the computer has to do a lot of  work even for simple tasks. Because of that, you have to do a lot of work to  write the code for a computer to even do simple tasks. In addition, programming  tasks are usually not very simple. Therefore, we neeed a way to make this  process easier on ourselves. There are several ways to do this, including:&lt;/p&gt; &lt;ul class="itemizedlist"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;Write code in a high-level language instead of assembly  language&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;Have lots of pre-written code that you can cut and paste  into your own programs&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;Have a set of functions on the system that are shared among  any program that wishes to use it&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p class="para"&gt;All three of these are usually used to some degree in any given  project. The first option will be explored further in &lt;span class="chapterjump"&gt;Chapter 11&lt;/span&gt;. The second option is  useful but it suffers from some drawbacks, including:&lt;/p&gt; &lt;ul class="itemizedlist"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;Code that is copied often has to be majorly modified to fit  the surrounding code.&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;Every program containing the copied code has the same code  in it, thus wasting a lot of space.&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;If a bug is found in any of the copied code it has to be  fixed in every application program.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p class="para"&gt;Therefore, the second option is usually used sparingly. It is  usually only used in cases where you copy and paste skeleton code for a specific  type of task, and add in your program-specific details. The third option is the  one that is used the most often. The third option includes having a central  repository of shared code. Then, instead of each program wasting space storing  the same copies of functions, they can simply point to the &lt;i class="emphasis"&gt;dynamic libraries&lt;/i&gt; which contain the functions they  need.&lt;/p&gt;&lt;a name="211"&gt;&lt;/a&gt;&lt;a name="IDX-130"&gt;&lt;/a&gt; &lt;p class="para"&gt;If a bug is found in one of these functions, it only has to be  fixed within the single function library file, and all applications which use it  are automatically updated. The main drawback with this approach is that it  creates some dependency problems, including:&lt;/p&gt; &lt;ul class="itemizedlist"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;If multiple applications are all using the same file, how do  we know when it is safe to delete the file? For example, if three applications  are sharing a file of functions and 2 of the programs are deleted, how does the  system know that there still exists an application that uses that code, and  therefore it shouldn't be deleted?&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;Some programs inadvertantly rely on bugs within shared  functions. Therefore, if upgrading the shared functions fixes a bug that a  program depended on, it could cause that application to cease  functioning.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p class="para"&gt;These problems are what lead to what is known as "DLL hell".  However, it is generally assumed that the advantages outweigh the  disadvantages.&lt;/p&gt; &lt;p class="last-para"&gt;In programming, these shared code files are referred to as &lt;i class="emphasis"&gt;shared libraries&lt;/i&gt; , &lt;i class="emphasis"&gt;dynamic libraries,  shared objects, dynamic-link libraries, DLLs,&lt;/i&gt; or &lt;i class="emphasis"&gt;.so  files&lt;/i&gt;.&lt;sup&gt;[&lt;a href="http://www2.blogger.com/post-edit.g?blogID=8901974503278002812&amp;postID=2114339705057527230#ftn.N84" name="N84"&gt;1&lt;/a&gt;]&lt;/sup&gt; We will refer to all of  these as &lt;i class="emphasis"&gt;dynamic libraries.&lt;/i&gt; &lt;/p&gt;&lt;/div&gt; &lt;div class="footnotes"&gt; &lt;div class="footnote"&gt; &lt;p&gt;&lt;sup&gt;[&lt;a href="http://www2.blogger.com/post-edit.g?blogID=8901974503278002812&amp;amp;postID=2114339705057527230#N84" name="ftn.N84"&gt;1&lt;/a&gt;]&lt;/sup&gt;Each of these terms have  slightly different meanings, but most people use them interchangeably anyway.  Specifically, this chapter will cover dynamic libraries, but not shared  libraries. Shared libraries are dynamic libraries which are built using &lt;i class="citetitle"&gt;position-independent code&lt;/i&gt; (often abbreviated PIC) which is  outside the scope of this book. However, shared libraries and dynamic libraries  are used in the same way by users and programs; the linker just links them  differently.&lt;/p&gt;&lt;div class="section"&gt; &lt;h2 class="first-section-title"&gt;&lt;a name="212"&gt;&lt;/a&gt;&lt;a name="ch08lev1sec1"&gt;&lt;/a&gt;Using a  Dynamic Library&lt;/h2&gt; &lt;p class="first-para"&gt;The program we will examine here is simple - it writes the  characters &lt;span class="fixed"&gt;hello world&lt;/span&gt; to the screen and exits. The  regular program, &lt;span class="fixed"&gt;helloworld-nolib. s&lt;/span&gt;, looks like  this:&lt;/p&gt;&lt;a name="213"&gt;&lt;/a&gt;&lt;a name="IDX-131"&gt;&lt;/a&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;#PURPOSE:  This program writes the message "hello world" and&lt;br /&gt;#          exits&lt;br /&gt;#&lt;br /&gt;&lt;br /&gt;.include "linux.s"&lt;br /&gt;&lt;br /&gt;.section .data&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;helloworld:&lt;br /&gt;.ascii "hello world\n"&lt;br /&gt;helloworld_end:&lt;br /&gt;&lt;br /&gt;.equ helloworld_len, helloworld_end - helloworld&lt;br /&gt;&lt;br /&gt;.section .text&lt;br /&gt;.globl _start&lt;br /&gt;_start:&lt;br /&gt;movl  $STDOUT, %ebx&lt;br /&gt;movl  $helloworld, %ecx&lt;br /&gt;movl  $helloworld_len, %edx&lt;br /&gt;movl  $SYS_WRITE, %eax&lt;br /&gt;int   $LINUX_SYSCALL&lt;br /&gt;&lt;br /&gt;movl  $0, %ebx&lt;br /&gt;movl  $SYS_EXIT, %eax&lt;br /&gt;int   $LINUX_SYSCALL&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;That's not too long. However, take a look at how short &lt;span class="fixed"&gt;helloworld-lib&lt;/span&gt; is which uses a library:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;#PURPOSE:  This program writes the message "hello world" and&lt;br /&gt;#          exits&lt;a name="214"&gt;&lt;/a&gt;&lt;a name="IDX-132"&gt;&lt;/a&gt;&lt;br /&gt;#&lt;br /&gt;&lt;br /&gt;.section .data&lt;br /&gt;&lt;br /&gt;helloworld:&lt;br /&gt;.ascii "hello world\n\0"&lt;br /&gt;&lt;br /&gt;.section .text&lt;br /&gt;.globl _start&lt;br /&gt;_start:&lt;br /&gt;pushl $helloworld&lt;br /&gt;call  printf&lt;br /&gt;&lt;br /&gt;pushl $0&lt;br /&gt;call  exit&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;It's even shorter!&lt;/p&gt; &lt;p class="para"&gt;Now, building programs which use dynamic libraries is a little  different than normal. You can build the first program normally by doing  this:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;as helloworld-nolib.s -o helloworld-nolib.o&lt;br /&gt;ld helloworld-nolib.o -o helloworld-nolib&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;However, in order to build the second program, you have to do  this:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;as helloworld-lib.s -o helloworld-lib.o&lt;br /&gt;ld -dynamic-linker /lib/ld-linux.so.2 \&lt;br /&gt; -o helloworld-lib helloworld-lib.o -1c&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;Remember, the backslash in the first line simply means that the  command continues on the next line. The option &lt;span class="fixed"&gt;-dynamic-linker  /lib/ld-linux.so.2&lt;/span&gt; allows our program to be linked to libraries. This  builds the executable so that before executing, the operating system will load  the &lt;a name="215"&gt;&lt;/a&gt;&lt;a name="IDX-133"&gt;&lt;/a&gt;program &lt;span class="fixed"&gt;/lib/ld-linux.so.2&lt;/span&gt; to load in external libraries and link  them with the program. This program is known as a &lt;i class="emphasis"&gt;dynamic  linker&lt;/i&gt;.&lt;/p&gt; &lt;p class="para"&gt;The &lt;span class="fixed"&gt;-lc&lt;/span&gt; option says to link to the &lt;span class="fixed"&gt;c&lt;/span&gt; library, named &lt;span class="fixed"&gt;libc.so&lt;/span&gt; on  GNU/Linux systems. Given a library name, &lt;span class="fixed"&gt;c&lt;/span&gt; in this case  (usually library names are longer than a single letter), the GNU/Linux linker  prepends the string &lt;span class="fixed"&gt;lib&lt;/span&gt; to the beginning of the library  name and appends &lt;span class="fixed"&gt;.so&lt;/span&gt; to the end of it to form the  library's filename. This library contains many functions to automate all types  of tasks. The two we are using are &lt;span class="fixed"&gt;printf&lt;/span&gt;, which prints  strings, and &lt;span class="fixed"&gt;exit&lt;/span&gt;, which exits the program.&lt;/p&gt; &lt;p class="last-para"&gt;Notice that the symbols &lt;span class="fixed"&gt;printf&lt;/span&gt; and  &lt;span class="fixed"&gt;exit&lt;/span&gt; are simply referred to by name within the program.  In previous chapters, the linker would resolve all of the names to physical  memory addresses, and the names would be thrown away. When using dynamic  linking, the name itself resides within the executable, and is resolved by the  dynamic linker when it is run. When the program is run by the user, the dynamic  linker loads the dynamic libraries listed in our link statement, and then finds  all of the function and variable names that were named by our program but not  found at link time, and matches them up with corresponding entries in the shared  libraries it loads. It then replaces all of the names with the addresses which  they are loaded at. This sounds time-consuming. It is to a small degree, but it  only happens once - at program startup time.&lt;/p&gt;&lt;h2 class="first-section-title"&gt;&lt;a name="216"&gt;&lt;/a&gt;&lt;a name="ch08lev1sec2"&gt;&lt;/a&gt;How  Dynamic Libraries Work&lt;/h2&gt; &lt;p class="first-para"&gt;In our first programs, all of the code was contained within  the source file. Such programs are called &lt;i class="emphasis"&gt;statically-linked  executables&lt;/i&gt;, because they contained all of the necessary functionality for  the program that wasn't handled by the kernel. In the programs we wrote in &lt;span class="chapterjump"&gt;Chapter 6&lt;/span&gt;, we used  both our main program file and files containing routines used by multiple  programs. In these cases, we combined all of the code together using the linker  at link-time, so it was still statically-linked. However, in the &lt;span class="fixed"&gt;helloworld-lib&lt;/span&gt; program, we started using dynamic libraries.  When you use dynamic libraries, your program is then &lt;i class="emphasis"&gt;dynamically-linked,&lt;/i&gt; which &lt;a name="217"&gt;&lt;/a&gt;&lt;a name="IDX-134"&gt;&lt;/a&gt;means that not all of the code needed to run the program is  actually contained within the program file itself, but in external  libraries.&lt;/p&gt; &lt;p class="para"&gt;When we put the &lt;span class="fixed"&gt;-lc&lt;/span&gt; on the command to  link the &lt;span class="fixed"&gt;helloworld&lt;/span&gt; program, it told the linker to use  the &lt;span class="fixed"&gt;c&lt;/span&gt; library (&lt;span class="fixed"&gt;libc.so&lt;/span&gt;) to  look up any symbols that weren't already defined in &lt;span class="fixed"&gt;helloworld.o&lt;/span&gt;. However, it doesn't actually add any code to  our program, it just notes in the program where to look. When the &lt;span class="fixed"&gt;helloworld&lt;/span&gt; program begins, the file &lt;span class="fixed"&gt;/lib/ld-linux.so.2&lt;/span&gt; is loaded first. This is the dynamic  linker. This looks at our &lt;span class="fixed"&gt;helloworld&lt;/span&gt; program and sees  that it needs the &lt;span class="fixed"&gt;c&lt;/span&gt; library to run. So, it searches for  a file called &lt;span class="fixed"&gt;libc.so&lt;/span&gt; in the standard places (listed in  &lt;span class="fixed"&gt;/etc/ld.so.conf&lt;/span&gt; and in the contents of the &lt;span class="fixed"&gt;LD_LIBRARY_PATH&lt;/span&gt; environment variable), then looks in it for  all the needed symbols (&lt;span class="fixed"&gt;printf&lt;/span&gt; and &lt;span class="fixed"&gt;exit&lt;/span&gt; in this case), and then loads the library into the  program's virtual memory. Finally, it replaces all instances of &lt;span class="fixed"&gt;printf&lt;/span&gt; in the program with the actual location of &lt;span class="fixed"&gt;printf&lt;/span&gt; in the library.&lt;/p&gt; &lt;p class="para"&gt;Run the following command:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;ldd ./helloworld-nolib&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;It should report back &lt;span class="fixed"&gt;not a dynamic  executable&lt;/span&gt;. This is just like we said - &lt;span class="fixed"&gt;helloworld-nolib&lt;/span&gt; is a statically-linked executable. However,  try this:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;ldd ./helloworld-lib&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;It will report back something like&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;      libc.so.6 =&gt; /lib/libc.so.6 (0x4001d000)&lt;br /&gt;    /lib/ld-linux.so.2 =&gt; /lib/ld-linux.so.2 (0x400000000)&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="last-para"&gt;The numbers in parenthesis may be different on your system.  This means that the program &lt;span class="fixed"&gt;helloworld&lt;/span&gt; is linked to  &lt;span class="fixed"&gt;libc.so.6&lt;/span&gt; (the &lt;span class="fixed"&gt;.6&lt;/span&gt; is the  version number), which is found at &lt;span class="fixed"&gt;/lib/libc.so.6&lt;/span&gt;, and  &lt;span class="fixed"&gt;/lib/ld-linux.so.2&lt;/span&gt; is found at &lt;span class="fixed"&gt;/lib/ld-linux.so.2&lt;/span&gt;. These libraries have to be loaded before  the program can &lt;a name="218"&gt;&lt;/a&gt;&lt;a name="IDX-135"&gt;&lt;/a&gt;be run. If you are  interested, run the &lt;span class="fixed"&gt;ldd&lt;/span&gt; program on various programs  that are on your Linux distribution, and see what libraries they rely on.&lt;/p&gt;&lt;div class="chapter"&gt;&lt;a name="ch08"&gt;&lt;/a&gt; &lt;div class="section"&gt; &lt;h2 class="first-section-title"&gt;&lt;a name="219"&gt;&lt;/a&gt;&lt;a name="ch08lev1sec3"&gt;&lt;/a&gt;Finding  Information About Libraries&lt;/h2&gt; &lt;p class="first-para"&gt;Okay, so now that you know about libraries, the question is,  how do you find out what libraries you have on your system and what they do?  Well, let's skip that question for a minute and ask another question: How do  programmers describe functions to each other in their documentation? Let's take  a look at the function &lt;span class="fixed"&gt;printf&lt;/span&gt;. Its calling interface  (usually referred to as a &lt;i class="emphasis"&gt;prototype&lt;/i&gt;) looks like this:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;int printf(char *string, ...);&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;In Linux, functions are described in the C programming language.  In fact, most Linux programs are written in C. That is why most documentation  and binary compatibility is defined using the C language. The interface to the  &lt;span class="fixed"&gt;printf&lt;/span&gt; function above is described using the C  programming language.&lt;/p&gt; &lt;p class="para"&gt;This definition means that there is a function &lt;span class="fixed"&gt;printf&lt;/span&gt;. The things inside the parenthesis are the function's  parameters or arguments. The first parameter here is &lt;span class="fixed"&gt;char  *string&lt;/span&gt;. This means there is a parameter named &lt;span class="fixed"&gt;string&lt;/span&gt; (the name isn't important, except to use for talking  about it), which has a type &lt;span class="fixed"&gt;char *.char&lt;/span&gt; means that it  wants a single-byte character. The * after it means that it doesn't actually  want a character as an argument, but instead it wants the address of a character  or sequence of characters. If you look back at our &lt;span class="fixed"&gt;helloworld  program&lt;/span&gt;, you will notice that the function call looked like this:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt; pushl $hello&lt;br /&gt;call  printf&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;So, we pushed the address of the &lt;span class="fixed"&gt;hello&lt;/span&gt;  string, rather than the actual characters. You might notice that we didn't push  the length of the string. The way that &lt;span class="fixed"&gt;printf&lt;/span&gt; found the  end of the string was because we ended it with a null character &lt;a name="220"&gt;&lt;/a&gt;&lt;a name="IDX-136"&gt;&lt;/a&gt;&lt;span class="fixed"&gt;(\0)&lt;/span&gt;. Many functions  work that way, especially C language functions. The &lt;span class="fixed"&gt;int&lt;/span&gt;  before the function definition tell what type of value the function will return  in &lt;span class="fixed"&gt;%eax&lt;/span&gt; when it returns. &lt;span class="fixed"&gt;printf&lt;/span&gt; will return an &lt;span class="fixed"&gt;int&lt;/span&gt; when it's  through. Now, after the &lt;span class="fixed"&gt;char *string&lt;/span&gt;, we have a series  of periods, .... This means that it can take an indefinite number of additional  arguments after the string. Most functions can only take a specified number of  arguments. &lt;span class="fixed"&gt;printf&lt;/span&gt;, however, can take many. It will look  into the &lt;span class="fixed"&gt;string&lt;/span&gt; parameter, and everywhere it sees the  characters &lt;span class="fixed"&gt;%s&lt;/span&gt;, it will look for another string from the  stack to insert, and everywhere it sees &lt;span class="fixed"&gt;%d&lt;/span&gt; it will look  for a number from the stack to insert. This is best described using an  example:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;#PURPOSE:  This program is to demonstrate how to call printf&lt;br /&gt;#&lt;br /&gt;&lt;br /&gt;.section .data&lt;br /&gt;&lt;br /&gt;#This string is called the format string.  It's the first&lt;br /&gt;#parameter, and printf uses it to find out how many parameters&lt;br /&gt;#it was given, and what kind they are.&lt;br /&gt;firststring:&lt;br /&gt;.ascii "Hello! %s is a %s who loves the number %d\n\0"&lt;br /&gt;name:&lt;br /&gt;.ascii "Jonathan\0"&lt;br /&gt;personstring:&lt;br /&gt;.ascii "person\0"&lt;br /&gt;#This could also have been an .equ, but we decided to give it&lt;br /&gt;#a real memory location just for kicks&lt;br /&gt;numberloved:&lt;br /&gt;.long 3&lt;br /&gt;&lt;br /&gt;.section .text&lt;br /&gt;.globl _start&lt;br /&gt;_start:&lt;br /&gt;#note that the parameters are passed in the&lt;br /&gt;#reverse order that they are listed in the&lt;br /&gt;#function's prototype.&lt;a name="221"&gt;&lt;/a&gt;&lt;a name="IDX-137"&gt;&lt;/a&gt;&lt;br /&gt;pushl numberloved    #This is the %d&lt;br /&gt;pushl $personstring  #This is the second %s&lt;br /&gt;pushl $name          #This is the first %s&lt;br /&gt;pushl $firststring   #This is the format string&lt;br /&gt;                    #in the prototype&lt;br /&gt;call printf&lt;br /&gt;&lt;br /&gt;pushl $0&lt;br /&gt;call  exit&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;Type it in with the filename &lt;span class="fixed"&gt;printf-example.s&lt;/span&gt;, and then do the following commands:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;as printf-example.s -o printf-example.o&lt;br /&gt;ld printf-example.o -o printf-example -lc \&lt;br /&gt; -dynamic-linker /lib/ld-linux.so.2&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;Then run the program with &lt;span class="fixed"&gt;./printf-example&lt;/span&gt;, and it should say this:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;Hello! Jonathan is a person who loves the number 3&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;Now, if you look at the code, you'll see that we actually push the  format string last, even though it's the first parameter listed. You always push  a functions parameters in reverse order.&lt;sup&gt;[&lt;a href="http://www2.blogger.com/post-edit.g?blogID=8901974503278002812&amp;postID=2114339705057527230#ftn.N148" name="N148"&gt;2&lt;/a&gt;]&lt;/sup&gt; You may be wondering how the &lt;span class="fixed"&gt;printf&lt;/span&gt; function knows how many parameters there are. Well, it  searches through your string, and counts how many &lt;span class="fixed"&gt;%d&lt;/span&gt;s  and &lt;span class="fixed"&gt;%s&lt;/span&gt;s it finds, and then grabs that number of  parameters from the stack. If the parameter matches a &lt;span class="fixed"&gt;%d&lt;/span&gt;, it treats it as a number, and if it &lt;a name="222"&gt;&lt;/a&gt;&lt;a name="IDX-138"&gt;&lt;/a&gt;matches a &lt;span class="fixed"&gt;%s&lt;/span&gt;, it treats it as a  pointer to a null-terminated string. &lt;span class="fixed"&gt;printf&lt;/span&gt; has many  more features than this, but these are the most-used ones. So, as you can see,  &lt;span class="fixed"&gt;printf&lt;/span&gt; can make output a lot easier, but it also has a  lot of overhead, because it has to count the number of characters in the string,  look through it for all of the control characters it needs to replace, pull them  off the stack, convert them to a suitable representation (numbers have to be  converted to strings, etc), and stick them all together appropriately.&lt;/p&gt; &lt;p class="para"&gt;We've seen how to use the C programming language prototypes to  call library functions. To use them effectively, however, you need to know  several more of the possible data types for reading functions. Here are the main  ones:&lt;/p&gt; &lt;p class="para"&gt;&lt;span class="fixed"&gt;int&lt;/span&gt; &lt;/p&gt; &lt;ul class="simple-list"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;An &lt;span class="fixed"&gt;int&lt;/span&gt; is an integer number (4  bytes on x86 processor).&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p class="para"&gt;&lt;span class="fixed"&gt;long&lt;/span&gt; &lt;/p&gt; &lt;ul class="simple-list"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;A &lt;span class="fixed"&gt;long&lt;/span&gt; is also an integer number (4  bytes on an x86 processor).&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p class="para"&gt;&lt;span class="fixed"&gt;long long&lt;/span&gt; &lt;/p&gt; &lt;ul class="simple-list"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;A &lt;span class="fixed"&gt;long long&lt;/span&gt; is an integer number  that's larger than a &lt;span class="fixed"&gt;long&lt;/span&gt; (8 bytes on an x86  processor).&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p class="para"&gt;&lt;span class="fixed"&gt;short&lt;/span&gt; &lt;/p&gt; &lt;ul class="simple-list"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;A short is an integer number that's shorter than an &lt;span class="fixed"&gt;int&lt;/span&gt; (2 bytes on an x86 processor).&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p class="para"&gt;&lt;span class="fixed"&gt;char&lt;/span&gt; &lt;/p&gt; &lt;ul class="simple-list"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;A &lt;span class="fixed"&gt;char&lt;/span&gt; is a single-byte integer  number. This is mostly used for storing character data, since ASCII strings  usually are represented with one byte per character.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;a name="223"&gt;&lt;/a&gt;&lt;a name="IDX-139"&gt;&lt;/a&gt; &lt;p class="para"&gt;&lt;span class="fixed"&gt;float&lt;/span&gt; &lt;/p&gt; &lt;ul class="simple-list"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;A &lt;span class="fixed"&gt;float&lt;/span&gt; is a floating-point number  (4 bytes on an x86 processor). Floating-point numbers will be explained in more  depth in the Section called &lt;i class="emphasis"&gt;Floating-point Numbers&lt;/i&gt; in &lt;span class="chapterjump"&gt;Chapter  10&lt;/span&gt;.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p class="para"&gt;&lt;span class="fixed"&gt;.double&lt;/span&gt; &lt;/p&gt; &lt;ul class="simple-list"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;A &lt;span class="fixed"&gt;double&lt;/span&gt; is a floating-point number  that is larger than a float (8 bytes on an x86 processor).&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p class="para"&gt;&lt;span class="fixed"&gt;unsigned&lt;/span&gt; &lt;/p&gt; &lt;ul class="simple-list"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;&lt;span class="fixed"&gt;unsigned&lt;/span&gt; is a modifier used for any  of the above types which keeps them from being used as signed quantities. The  difference between signed and unsigned numbers will be discussed in &lt;span class="chapterjump"&gt;Chapter  10&lt;/span&gt;.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p class="para"&gt;&lt;span class="fixed"&gt;*&lt;/span&gt; &lt;/p&gt; &lt;ul class="simple-list"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;An asterisk (&lt;span class="fixed"&gt;*&lt;/span&gt;) is used to denote  that the data isn't an actual value, but instead is a pointer to a location  holding the given value (4 bytes on an x86 processor). So, let's say in memory  location &lt;span class="fixed"&gt;my_location&lt;/span&gt; you have the number 20 stored. If  the prototype said to pass an &lt;span class="fixed"&gt;int&lt;/span&gt;, you would use direct  addressing mode and do &lt;span class="fixed"&gt;pushl my_location&lt;/span&gt;. However, if  the prototype said to pass an &lt;span class="fixed"&gt;int *&lt;/span&gt;, you would do &lt;span class="fixed"&gt;pushl $my_location&lt;/span&gt; - an immediate mode push of the address  that the value resides in. In addition to indicating the address of a single  value, pointers can also be used to pass a sequence of consecutive locations,  starting with the one pointed to by the given value. This is called an  array.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p class="para"&gt;&lt;span class="fixed"&gt;struct&lt;/span&gt; &lt;/p&gt; &lt;ul class="simple-list"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;A &lt;span class="fixed"&gt;struct&lt;/span&gt; is a set of data items  that have been put together under a name. For example you could declare:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;struct teststruct {&lt;br /&gt;int a;&lt;a name="224"&gt;&lt;/a&gt;&lt;a name="IDX-140"&gt;&lt;/a&gt;&lt;br /&gt;char *b;&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="last-para"&gt;and any time you ran into &lt;span class="fixed"&gt;struct  teststruct&lt;/span&gt; you would know that it is actually two words right next to  each other, the first being an integer, and the second a pointer to a character  or group of characters. You never see structs passed as arguments to functions.  Instead, you usually see pointers to structs passed as arguments. This is  because passing structs to functions is fairly complicated, since they can take  up so many storage locations.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p class="para"&gt;&lt;span class="fixed"&gt;typedef&lt;/span&gt; &lt;/p&gt; &lt;ul class="simple-list"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;A &lt;span class="fixed"&gt;typedef&lt;/span&gt; basically allows you to  rename a type. For example, I can do &lt;span class="fixed"&gt;typedef int  myowntype&lt;/span&gt;; in a C program, and any time I typed &lt;span class="fixed"&gt;myowntype&lt;/span&gt;, it would be just as if I typed &lt;span class="fixed"&gt;int&lt;/span&gt;. This can get kind of annoying, because you have to look  up what all of the typedefs and structs in a function prototype really mean.  However, &lt;span class="fixed"&gt;typedef&lt;/span&gt;s are useful for giving types more  meaningful and descriptive names.&lt;/p&gt; &lt;p class="para"&gt;&lt;b&gt;Compatibility Note:&lt;/b&gt; The listed sizes are for  intel-compatible (x86) machines. Other machines will have different sizes. Also,  even when parameters shorter than a word are passed to functions, they are  passed as longs on the stack.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p class="last-para"&gt;That's how to read function documentation. Now, let's get  back to the question of how to find out about libraries. Most of your system  libraries are in &lt;span class="fixed"&gt;/usr/lib&lt;/span&gt; or &lt;span class="fixed"&gt;/lib&lt;/span&gt;. If you want to just see what symbols they define, just  run &lt;span class="fixed"&gt;objdump -R FILENAME&lt;/span&gt; where &lt;span class="fixed"&gt;FILENAME&lt;/span&gt; is the full path to the library. The output of that  isn't too helpful, though, for finding an interface that you might need.  Usually, you have to know what library you want at the beginning, and then just  read the documentation. Most libraries have manuals or man pages for their  functions. The web is the best source of documentation for libraries. Most  libraries from the &lt;a name="225"&gt;&lt;/a&gt;&lt;a name="IDX-141"&gt;&lt;/a&gt;GNU project also have  info pages on them, which are a little more thorough than man pages.&lt;/p&gt;&lt;/div&gt; &lt;div class="footnotes"&gt; &lt;div class="footnote"&gt; &lt;p&gt;&lt;sup&gt;[&lt;a href="http://www2.blogger.com/post-edit.g?blogID=8901974503278002812&amp;postID=2114339705057527230#N148" name="ftn.N148"&gt;2&lt;/a&gt;]&lt;/sup&gt;The reason that parameters  are pushed in the reverse order is because of functions which take a variable  number of parameters like &lt;span class="fixed"&gt;printf&lt;/span&gt;. The parameters pushed  in last will be in a known position relative to the top of the stack. The  program can then use these parameters to determine where on the stack the  additional arguments are, and what type they are. For example, &lt;span class="fixed"&gt;printf&lt;/span&gt; uses the format string to determine how many other  parameters are being sent. If we pushed the known arguments first, you wouldn't  be able to tell where they were on the stack.&lt;/p&gt;&lt;div class="chapter"&gt;&lt;a name="ch08"&gt;&lt;/a&gt; &lt;div class="section"&gt; &lt;h2 class="first-section-title"&gt;&lt;a name="226"&gt;&lt;/a&gt;&lt;a name="ch08lev1sec4"&gt;&lt;/a&gt;Useful  Functions&lt;/h2&gt; &lt;p class="first-para"&gt;Several useful functions you will want to be aware of from  the c library include:&lt;/p&gt; &lt;ul class="itemizedlist"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;&lt;span class="fixed"&gt;size_t strlen (const char *s)&lt;/span&gt;  calculates the size of null-terminated strings.&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;&lt;span class="fixed"&gt;int strcmp (const char *sl, const char  *s2)&lt;/span&gt; compares two strings alphabetically.&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;&lt;span class="fixed"&gt;char * strdup (const char *s)&lt;/span&gt; takes  the pointer to a string, and creates a new copy in a new location, and returns  the new location.&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;&lt;span class="fixed"&gt;FILE * fopen (const char *filename, const  char *opentype)&lt;/span&gt; opens a managed, buffered file (allows easier reading and  writing than using file descriptors directly).&lt;sup&gt;[&lt;a href="http://www2.blogger.com/post-edit.g?blogID=8901974503278002812&amp;amp;postID=2114339705057527230#ftn.N42" name="N42"&gt;3&lt;/a&gt;]&lt;/sup&gt;, &lt;sup&gt;[&lt;a href="http://www2.blogger.com/post-edit.g?blogID=8901974503278002812&amp;postID=2114339705057527230#ftn.N59" name="N59"&gt;4&lt;/a&gt;]&lt;/sup&gt; &lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;&lt;span class="fixed"&gt;int fclose (FILE * stream)&lt;/span&gt; closes a  file opened with &lt;span class="fixed"&gt;fopen&lt;/span&gt;.&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;&lt;span class="fixed"&gt;char * fgets (char *s, int count, FILE  *stream)&lt;/span&gt; fetches a line of characters into string &lt;span class="fixed"&gt;s&lt;/span&gt;.&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;&lt;span class="fixed"&gt;int fputs (const char *s, FILE  *stream)&lt;/span&gt; writes a string to the given open file.&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;&lt;span class="fixed"&gt;int fprintf (FILE *stream, const char  *template, ...)&lt;/span&gt; is just like &lt;span class="fixed"&gt;printf&lt;/span&gt;, but it uses  an open file rather than defaulting to using standard output.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;a name="227"&gt;&lt;/a&gt;&lt;a name="IDX-142"&gt;&lt;/a&gt; &lt;p class="last-para"&gt;You can find the complete manual on this library by going to  &lt;a class="url" href="http://www.gnu.org/software/libc/manual/" target="_top"&gt;http://www.gnu.org/software/libc/manual/&lt;/a&gt; &lt;/p&gt;&lt;/div&gt; &lt;div class="footnotes"&gt; &lt;div class="footnote"&gt; &lt;p&gt;&lt;sup&gt;[&lt;a href="http://www2.blogger.com/post-edit.g?blogID=8901974503278002812&amp;amp;postID=2114339705057527230#N42" name="ftn.N42"&gt;3&lt;/a&gt;]&lt;/sup&gt;&lt;span class="fixed"&gt;stdin&lt;/span&gt;,  &lt;span class="fixed"&gt;stdout&lt;/span&gt;, and &lt;span class="fixed"&gt;stderr&lt;/span&gt; (all lower  case) can be used in these programs to refer to the files of their corresponding  file descriptors.&lt;/p&gt;&lt;/div&gt; &lt;div class="footnote"&gt; &lt;p&gt;&lt;sup&gt;[&lt;a href="http://www2.blogger.com/post-edit.g?blogID=8901974503278002812&amp;amp;postID=2114339705057527230#N59" name="ftn.N59"&gt;4&lt;/a&gt;]&lt;/sup&gt;&lt;span class="fixed"&gt;FILE&lt;/span&gt;  is a struct. You don't need to know its contents to use it. You only have to  store the pointer and pass it to the relevant other  functions.&lt;/p&gt;&lt;div class="chapter"&gt;&lt;a name="ch08"&gt;&lt;/a&gt; &lt;div class="section"&gt; &lt;h2 class="first-section-title"&gt;&lt;a name="228"&gt;&lt;/a&gt;&lt;a name="ch08lev1sec5"&gt;&lt;/a&gt;Building  a Dynamic Library&lt;/h2&gt; &lt;p class="first-para"&gt;Let's say that we wanted to take all of our shared code from  &lt;span class="chapterjump"&gt;Chapter 6&lt;/span&gt; and  build it into a dynamic library to use in our programs. The first thing we would  do is assemble them like normal:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;as write-record.s -o write-record.o&lt;br /&gt;as read-record.s -o read-record.o&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;Now, instead of linking them into a program, we want to link them  into a dynamic library. This changes our linker command to this:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;ld -shared write-record.o read-record.o -o librecord.so&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;This links both of these files together into a dynamic library  called &lt;span class="fixed"&gt;librecord.so&lt;/span&gt;. This file can now be used for  multiple programs. If we need to update the functions contained within it, we  can just update this one file and not have to worry about which programs use  it.&lt;/p&gt; &lt;p class="para"&gt;Let's look at how we would link against this library. To link the  &lt;span class="fixed"&gt;write-records&lt;/span&gt; program, we would do the following:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;as write-records.s -o write-records&lt;br /&gt;ld -L . -dynamic-linker /lib/ld-linux.so.2 \&lt;br /&gt; -o write-records -lrecord write-records.o&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;In this command, &lt;span class="fixed"&gt;-L .&lt;/span&gt; told the linker to  look for libraries in the current directory (it usually only searches &lt;span class="fixed"&gt;/lib&lt;/span&gt; directory, &lt;span class="fixed"&gt;/usr/lib&lt;/span&gt; directory,  and a few others). As we've seen, the option &lt;span class="fixed"&gt;-dynamic-linker  /lib/ld-linux.so.2&lt;/span&gt; specified the dynamic linker. The option &lt;span class="fixed"&gt;-lrecord&lt;/span&gt; tells the linker to search for functions in the file  named &lt;span class="fixed"&gt;librecord.so&lt;/span&gt;.&lt;/p&gt;&lt;a name="229"&gt;&lt;/a&gt;&lt;a name="IDX-143"&gt;&lt;/a&gt; &lt;p class="para"&gt;Now the &lt;span class="fixed"&gt;write-records&lt;/span&gt; program is built,  but it will not run. If we try it, we will get an error like the following:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;./write-records: error while loading shared libraries:&lt;br /&gt;librecord.so: cannot open shared object file: No such&lt;br /&gt;file or directory&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;This is because, by default, the dynamic linker only searches  &lt;span class="fixed"&gt;/lib&lt;/span&gt;, &lt;span class="fixed"&gt;/usr/lib&lt;/span&gt;, and whatever  directories are listed in &lt;span class="fixed"&gt;/etc/ld.so.conf&lt;/span&gt; for  libraries. In order to run the program, you either need to move the library to  one of these directories, or execute the following command:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;LD_LIBRARY_PATH=.&lt;br /&gt;export LD_LIBRARY_PATH&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;Alternatively, if that gives you an error, do this instead:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;setenv LD_LIBRARY_PATH .&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;Now, you can run &lt;span class="fixed"&gt;write-records&lt;/span&gt; normally  by typing &lt;span class="fixed"&gt;./write-records&lt;/span&gt;. Setting &lt;span class="fixed"&gt;LD_LIBRARY_PATH&lt;/span&gt; tells the linker to add whatever paths you  give it to the library search path for dynamic libraries.&lt;/p&gt; &lt;p class="para"&gt;For further information about dynamic linking, see the following  sources on the Internet:&lt;/p&gt; &lt;ul class="itemizedlist"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;The man page for &lt;span class="fixed"&gt;ld.so&lt;/span&gt; contains a  lot of information about how the Linux dynamic linker works.&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;&lt;a class="url" href="http://www.benyossef.com/presentations/dlink/" target="_top"&gt;http://www.benyossef.com/presentations/dlink/&lt;/a&gt; is a great  presentation on dynamic linking in Linux.&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;&lt;a class="url" href="http://www.linuxjournal.com/article.php?sid=1059" target="_top"&gt;http://www.linuxjournal.com/article.php?sid=1059&lt;/a&gt; and &lt;a class="url" href="http://www.linuxjournal.com/article.php?sid=1060" target="_top"&gt;http://www.linuxjournal.com/article.php?sid=1060&lt;/a&gt; provide a good  introduction &lt;a name="230"&gt;&lt;/a&gt;&lt;a name="IDX-144"&gt;&lt;/a&gt;to the ELF file format, with  more detail available at &lt;a class="url" href="http://www.cs.ucdavis.edu/%7Ehaungs/paper/node10.html" target="_top"&gt;http://www.cs.ucdavis.edu/~haungs/paper/node10.html&lt;/a&gt; &lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;&lt;a class="url" href="http://www.iecc.com/linker/linker10.html" target="_top"&gt;http://www.iecc.com/linker/linker10.html&lt;/a&gt; contains a great  description of how dynamic linking works with ELF files.&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;&lt;a class="url" href="http://linux4u.jinr.ru/usoft/WWW/www_debian.org/Documentation/elf/node21.html" target="_top"&gt;http://linux4u.jinr.ru/usoft/WWW/www_debian.org/Documentation/elf/node21.html&lt;/a&gt;  contains a good introduction to programming position-independent code for shared  libraries under Linux.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="section"&gt; &lt;h2 class="first-section-title"&gt;&lt;a name="231"&gt;&lt;/a&gt;&lt;a name="ch08lev1sec6"&gt;&lt;/a&gt;Review&lt;/h2&gt; &lt;div class="section"&gt; &lt;h3 class="sect3-title"&gt;&lt;a name="232"&gt;&lt;/a&gt;&lt;a name="ch08lev2sec1"&gt;&lt;/a&gt;Know the  Concepts&lt;/h3&gt; &lt;ul class="itemizedlist"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;What are the advantages and disadvantages of shared  libraries?&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;Given a library named 'foo', what would the library's  filename be?&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;What does the &lt;span class="fixed"&gt;ldd&lt;/span&gt; command do?&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;Let's say we had the files &lt;span class="fixed"&gt;foo.o&lt;/span&gt;  and &lt;span class="fixed"&gt;bar.o&lt;/span&gt;, and you wanted to link them together, and  dynamically link them to the library 'kramer'. What would the linking command be  to generate the final executable?&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;What is &lt;i class="emphasis"&gt;typedef&lt;/i&gt; for?&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;What are &lt;i class="emphasis"&gt;structs&lt;/i&gt; for?&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;What is the difference between a data element of type &lt;i class="emphasis"&gt;int&lt;/i&gt; and &lt;i class="emphasis"&gt;int&lt;/i&gt; *? How would you access  them differently in your program?&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;If you had a object file called &lt;span class="fixed"&gt;foo.o&lt;/span&gt;, what would be the command to create a shared library  called 'bar'?&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;What is the purpose of LD_LIBRARY_PATH?&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;a name="233"&gt;&lt;/a&gt;&lt;a name="IDX-145"&gt;&lt;/a&gt;&lt;/div&gt; &lt;div class="section"&gt; &lt;h3 class="sect3-title"&gt;&lt;a name="234"&gt;&lt;/a&gt;&lt;a name="ch08lev2sec2"&gt;&lt;/a&gt;Use the  Concepts&lt;/h3&gt; &lt;ul class="itemizedlist"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;Rewrite one or more of the programs from the previous  chapters to print their results to the screen using &lt;span class="fixed"&gt;printf&lt;/span&gt; rather than returning the result as the exit status  code. Also, make the exit status code be 0.&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;Use the &lt;span class="fixed"&gt;factorial&lt;/span&gt; function you  developed in the Section called &lt;i class="emphasis"&gt;Recursive Functions&lt;/i&gt; in &lt;span class="chapterjump"&gt;Chapter 4&lt;/span&gt; to make a  shared library. Then re-write the main program so that it links with the library  dynamically.&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;Rewrite the program above so that it also links with the 'c'  library. Use the 'c' library's &lt;span class="fixed"&gt;printf&lt;/span&gt; function to  display the result of the &lt;span class="fixed"&gt;factorial&lt;/span&gt; call.&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;Rewrite the &lt;span class="fixed"&gt;toupper&lt;/span&gt; program so that  it uses the &lt;span class="fixed"&gt;c&lt;/span&gt; library functions for files rather than  system calls.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt; &lt;div class="section"&gt; &lt;h3 class="sect3-title"&gt;&lt;a name="235"&gt;&lt;/a&gt;&lt;a name="ch08lev2sec3"&gt;&lt;/a&gt;Going  Further&lt;/h3&gt; &lt;ul class="itemizedlist"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;Make a list of all the environment variables used by the  GNU/Linux dynamic linker.&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;Research the different types of executable file formats in  use today and in the history of computing. Tell the strengths and weaknesses of  each.&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;What kinds of programming are you interested in (graphics,  databbases, science, etc.)? Find a library for working in that area, and write a  program that makes some basic use of that library.&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;Research the use of &lt;span class="fixed"&gt;LD_PRELOAD&lt;/span&gt;.  What is it used for? Try building a shared library that contained the &lt;span class="fixed"&gt;exit&lt;/span&gt; function, and have it write a message to STDERR before  exitting. Use &lt;span class="fixed"&gt;LD_PRELOAD&lt;/span&gt; and run various programs with  it. What are the results?&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;a name="236"&gt;&lt;/a&gt;&lt;a name="IDX-146"&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8901974503278002812-2114339705057527230?l=programminggroundup.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://programminggroundup.blogspot.com/feeds/2114339705057527230/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8901974503278002812&amp;postID=2114339705057527230' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8901974503278002812/posts/default/2114339705057527230'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8901974503278002812/posts/default/2114339705057527230'/><link rel='alternate' type='text/html' href='http://programminggroundup.blogspot.com/2007/01/chapter-8-sharing-functions-with-code.html' title='Chapter 8: Sharing Functions with Code Libraries'/><author><name>Admin</name><uri>http://www.blogger.com/profile/13783659974416042562</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8901974503278002812.post-6312657414619967438</id><published>2007-01-31T18:17:00.000-08:00</published><updated>2007-01-31T20:18:38.328-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='robust programs'/><category scheme='http://www.blogger.com/atom/ns#' term='x86'/><category scheme='http://www.blogger.com/atom/ns#' term='asm'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='assembly language'/><title type='text'>Chapter 7: Developing Robust Programs</title><content type='html'>&lt;div class="highlights"&gt; &lt;p class="first-para"&gt;This chapter deals with developing programs that are &lt;i class="emphasis"&gt;robust.&lt;/i&gt; Robust programs are able to handle error conditions  gracefully. They are programs that do not crash no matter what the user does.  Building robust programs is essential to the practice of programming. Writing  robust programs takes discipline and work - it usually entails finding every  possible problem that can occur, and coming up with an action plan for your  program to take.&lt;/p&gt;&lt;/div&gt; &lt;div class="section"&gt; &lt;h2 class="sect2-title"&gt;&lt;a name="184"&gt;&lt;/a&gt;&lt;a name="ch07lev1sec1"&gt;&lt;/a&gt;Where Does the  Time Go?&lt;/h2&gt; &lt;p class="first-para"&gt;Programmers schedule poorly. In almost every programming  project, programmers will take two, four, or even eight times as long to develop  a program or function than they originally estimated. There are many reasons for  this problem, including:&lt;/p&gt; &lt;ul class="itemizedlist"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;Programmers don't always schedule time for meetings or other  non-coding activities that make up every day.&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;Programmers often underestimate feedback times (how long it  takes to pass change requests and approvals back and forth) for projects.&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;Programmers don't always understand the full scope of what  they are producing.&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;Programmers often have to estimate a schedule on a totally  different kind of project than they are used to, and thus are unable to schedule  accurately.&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;Programmers often underestimate the amount of time it takes  to get a program fully robust.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p class="para"&gt;The last item is the one we are interested in here. &lt;i class="emphasis"&gt;It takes a lot of time and effort to develop robust programs.&lt;/i&gt;  More so than people usually guess, including &lt;a name="185"&gt;&lt;/a&gt;&lt;a name="IDX-118"&gt;&lt;/a&gt;experienced programmers. Programmers get so focused on simply  solving the problem at hand that they fail to look at the possible side  issues.&lt;/p&gt; &lt;p class="para"&gt;In the &lt;span class="fixed"&gt;toupper&lt;/span&gt; program, we do not have  any course of action if the file the user selects does not exist. The program  will go ahead and try to work anyway. It doesn't report any error message so the  user won't even know that they typed in the name wrong. Let's say that the  destination file is on a network drive, and the network temporarily fails. The  operating system is returning a status code to us in &lt;span class="fixed"&gt;%eax&lt;/span&gt;, but we aren't checking it. Therefore, if a failure  occurs, the user is totally unaware. This program is definitely not robust. As  you can see, even in a simple program there are a lot of things that can go  wrong that a programmer must contend with.&lt;/p&gt; &lt;p class="last-para"&gt;In a large program, it gets much more problematic. There are  usually many more possible error conditions than possible successful conditions.  Therefore, you should always expect to spend the majority of your time checking  status codes, writing error handlers, and performing similar tasks to make your  program robust. If it takes two weeks to develop a program, it will likely take  at least two more to make it robust. Remember that every error message that pops  up on your screen had to be programmed in by someone.&lt;/p&gt;&lt;div class="section"&gt; &lt;h2 class="first-section-title"&gt;&lt;a name="186"&gt;&lt;/a&gt;&lt;a name="ch07lev1sec2"&gt;&lt;/a&gt;Some Tips  for Developing Robust Programs&lt;/h2&gt; &lt;div class="section"&gt; &lt;h3 class="sect3-title"&gt;&lt;a name="187"&gt;&lt;/a&gt;&lt;a name="ch07lev2sec1"&gt;&lt;/a&gt;User Testing&lt;/h3&gt; &lt;p class="first-para"&gt;Testing is one of the most essential things a programmer  does. If you haven't tested something, you should assume it doesn't work.  However, testing isn't just about making sure your program works, it's about  making sure your program doesn't break. For example, if I have a program that is  only supposed to deal with positive numbers, you need to test what happens if  the user enters a negative number. Or a letter. Or the number zero. You must  test what happens if they put spaces before their numbers, spaces after their  numbers, and other little &lt;a name="188"&gt;&lt;/a&gt;&lt;a name="IDX-119"&gt;&lt;/a&gt;possibilities. You  need to make sure that you handle the user's data in a way that makes sense to  the user, and that you pass on that data in a way that makes sense to the rest  of your program. When your program finds input that doesn't make sense, it needs  to perform appropriate actions. Depending on your program, this may include  ending the program, prompting the user to re-enter values, notifying a central  error log, rolling back an operation, or ignoring it and continuing.&lt;/p&gt; &lt;p class="para"&gt;Not only should you test your programs, you need to have others  test it as well. You should enlist other programmers and users of your program  to help you test your program. If something is a problem for your users, even if  it seems okay to you, it needs to be fixed. If the user doesn't know how to use  your program correctly, that should be treated as a bug that needs to be  fixed.&lt;/p&gt; &lt;p class="last-para"&gt;You will find that users find a lot more bugs in your program  than you ever could. The reason is that users don't know what the computer  expects. You know what kinds of data the computer expects, and therefore are  much more likely to enter data that makes sense to the computer. Users enter  data that makes sense to them. Allowing non-programmers to use your program for  testing purposes usually gives you much more accurate results as to how robust  your program truly is.&lt;/p&gt;&lt;/div&gt; &lt;div class="section"&gt; &lt;h3 class="sect3-title"&gt;&lt;a name="189"&gt;&lt;/a&gt;&lt;a name="ch07lev2sec2"&gt;&lt;/a&gt;Data Testing&lt;/h3&gt; &lt;p class="first-para"&gt;When designing programs, each of your functions needs to be  very specific about the type and range of data that it will or won't accept. You  then need to test these functions to make sure that they perform to  specification when handed the appropriate data. Most important is testing &lt;i class="emphasis"&gt;corner cases&lt;/i&gt; or &lt;i class="emphasis"&gt;edge cases.&lt;/i&gt; Corner  cases are the inputs that are most likely to cause problems or behave  unexpectedly.&lt;/p&gt; &lt;p class="para"&gt;When testing numeric data, there are several corner cases you  always need to test:&lt;/p&gt; &lt;ul class="itemizedlist"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;The number 0&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;The number 1&lt;/p&gt;&lt;a name="190"&gt;&lt;/a&gt;&lt;a name="IDX-120"&gt;&lt;/a&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;A number within the expected range&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;A number outside the expected range&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;The first number in the expected range&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;The last number in the expected range&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;The first number below the expected range&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;The first number above the expected range&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p class="para"&gt;For example, if I have a program that is supposed to accept values  between 5 and 200, I should test 0, 1, 4, 5, 153, 200, 201, and 255 at a minimum  (153 and 255 were randomly chosen inside and outside the range, respectively).  The same goes for any lists of data you have. You need to test that your program  behaves as expected for lists of 0 items, 1 item, massive numbers of items, and  so on. In addition, you should also test any turning points you have. For  example, if you have different code to handle people under and over age 30, for  example, you would need to test it on people of ages 29, 30, and 31 at  least.&lt;/p&gt; &lt;p class="last-para"&gt;There will be some internal functions that you assume get  good data because you have checked for errors before this point. However, while  in development you often need to check for errors anyway, as your other code may  have errors in it. To verify the consistency and validity of data during  development, most languages have a facility to easily check assumptions about  data correctness. In the C language there is the &lt;span class="fixed"&gt;assert&lt;/span&gt;  macro. You can simply put in your code &lt;span class="fixed"&gt;assert (a &gt;  b);&lt;/span&gt;, and it will give an error if it reaches that code when the condition  is not true. In addition, since such a check is a waste of time after your code  is stable, the &lt;span class="fixed"&gt;assert&lt;/span&gt; macro allows you to turn off  asserts at compile-time. This makes sure that your functions are receiving good  data without causing unnecessary slowdowns for code released to the  public.&lt;/p&gt;&lt;/div&gt; &lt;div class="section"&gt; &lt;h3 class="sect3-title"&gt;&lt;a name="191"&gt;&lt;/a&gt;&lt;a name="ch07lev2sec3"&gt;&lt;/a&gt;Module  Testing&lt;/h3&gt; &lt;p class="first-para"&gt;Not only should you test your program as a whole, you need  to test the individual &lt;a name="192"&gt;&lt;/a&gt;&lt;a name="IDX-121"&gt;&lt;/a&gt;pieces of your  program. As you develop your program, you should test individual functions by  providing it with data you create to make sure it responds appropriately.&lt;/p&gt; &lt;p class="para"&gt;In order to do this effectively, you have to develop functions  whose sole purpose is to call functions for testing. These are called &lt;i class="emphasis"&gt;drivers&lt;/i&gt; (not to be confused with hardware drivers). They  simply load your function, supply it with data, and check the results. This is  especially useful if you are working on pieces of an unfinished program. Since  you can't test all of the pieces together, you can create a driver program that  will test each function individually.&lt;/p&gt; &lt;p class="last-para"&gt;Also, the code you are testing may make calls to functions  not developed yet. In order to overcome this problem, you can write a small  function called a &lt;i class="emphasis"&gt;stub&lt;/i&gt; which simply returns the values  that function needs to proceed. For example, in an e-commerce application, I had  a function called &lt;span class="fixed"&gt;is_ready_to_checkout&lt;/span&gt;. Before I had  time to actually write the function I just set it to return true on every call  so that the functions which relied on it would have an answer. This allowed me  to test functions which relied on &lt;span class="fixed"&gt;is_ready_to_checkout&lt;/span&gt;  without the function being fully implemented.&lt;/p&gt;&lt;div class="section"&gt; &lt;h2 class="first-section-title"&gt;&lt;a name="193"&gt;&lt;/a&gt;&lt;a name="ch07lev1sec3"&gt;&lt;/a&gt;Handling  Errors Effectively&lt;/h2&gt; &lt;p class="first-para"&gt;Not only is it important to know how to test, but it is also  important to know what to do when an error is detected.&lt;/p&gt; &lt;div class="section"&gt; &lt;h3 class="sect3-title"&gt;&lt;a name="194"&gt;&lt;/a&gt;&lt;a name="ch07lev2sec4"&gt;&lt;/a&gt;Have an Error  Code for Everything&lt;/h3&gt; &lt;p class="first-para"&gt;Truly robust software has a unique error code for every  possible contingency. By simply knowing the error code, you should be able to  find the location in your code where that error was signalled.&lt;/p&gt;&lt;a name="195"&gt;&lt;/a&gt;&lt;a name="IDX-122"&gt;&lt;/a&gt; &lt;p class="para"&gt;This is important because the error code is usually all the user  has to go on when reporting errors. Therefore, it needs to be as useful as  possible.&lt;/p&gt; &lt;p class="last-para"&gt;Error codes should also be accompanied by descriptive error  messages. However, only in rare circumstances should the error message try to  predict &lt;i class="emphasis"&gt;why&lt;/i&gt; the error occurred. It should simply relate  what happened. Back in 1995 I worked for an Internet Service Provider. One of  the web browsers we supported tried to guess the cause for every network error,  rather than just reporting the error. If the computer wasn't connected to the  Internet and the user tried to connect to a website, it would say that there was  a problem with the Internet Service Provider, that the server was down, and that  the user should contact their Internet Service Provider to correct the problem.  Nearly a quarter of our calls were from people who had received this message,  but merely needed to connect to the Internet before trying to use their browser.  As you can see, trying to diagnose what the problem is can lead to a lot more  problems than it fixes. It is better to just report error codes and messages,  and have separate resources for the user to troubleshooting the application. A  troubleshooting guide, not the program itself, is an appropriate place to list  possible reasons and courses for action for each error message.&lt;/p&gt;&lt;/div&gt; &lt;div class="section"&gt; &lt;h3 class="sect3-title"&gt;&lt;a name="196"&gt;&lt;/a&gt;&lt;a name="ch07lev2sec5"&gt;&lt;/a&gt;Recovery  Points&lt;/h3&gt; &lt;p class="first-para"&gt;In order to simplify error handling, it is often useful to  break your program apart into distinct units, where each unit fails and is  recovered as a whole. For example, you could break your program up so that  reading the configuration file was a unit. If reading the configuration file  failed at any point (opening the file, reading the file, trying to decode the  file, etc.) then the program would simply treat it as a configuration file  problem and skip to the &lt;i class="emphasis"&gt;recovery point&lt;/i&gt; for that problem.  This way you greatly reduce the number of error-handling mechanism you need for  your program, because error recovery is done on a much more general level.&lt;/p&gt; &lt;p class="para"&gt;Note that even with recovery points, your error messages need to  be specific as to what the problem was. Recovery points are basic units for  error recovery, not for error detection. Error detection still needs to be  extremely exact, and the error &lt;a name="197"&gt;&lt;/a&gt;&lt;a name="IDX-123"&gt;&lt;/a&gt;reports need  exact error codes and messages.&lt;/p&gt; &lt;p class="para"&gt;When using recovery points, you often need to include cleanup code  to handle different contingencies. For example, in our configuration file  example, the recovery function would need to include code to check and see if  the configuration file was still open. Depending on where the error occurred,  the file may have been left open. The recovery function needs to check for this  condition, and any other condition that might lead to system instability, and  return the program to a consistent state.&lt;/p&gt; &lt;p class="last-para"&gt;The simplest way to handle recovery points is to wrap the  whole program into a single recovery point. You would just have a simple  error-reporting function that you can call with an error code and a message. The  function would print them and and simply exit the program. This is not usually  the best solution for real-world situations, but it is a good fall-back, last  resort mechanism.&lt;/p&gt;&lt;div class="section"&gt; &lt;h2 class="first-section-title"&gt;&lt;a name="198"&gt;&lt;/a&gt;&lt;a name="ch07lev1sec4"&gt;&lt;/a&gt;Making  Our Program More Robust&lt;/h2&gt; &lt;p class="first-para"&gt;This section will go through making the &lt;span class="fixed"&gt;add-year.s&lt;/span&gt; program from &lt;span class="chapterjump"&gt;Chapter 6&lt;/span&gt; a little more robust.&lt;/p&gt; &lt;p class="para"&gt;Since this is a pretty simple program, we will limit ourselves to  a single recovery point that covers the whole program. The only thing we will do  to recover is to print the error and exit. The code to do that is pretty  simple:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt; .include "linux.s"&lt;br /&gt;.equ ST_ERROR_CODE, 8&lt;br /&gt;.equ ST_ERROR_MSG, 12&lt;br /&gt;.globl error_exit&lt;br /&gt;.type error_exit, @function&lt;br /&gt;error_exit:&lt;br /&gt;pushl %ebp&lt;br /&gt;movl  %esp, %ebp&lt;a name="199"&gt;&lt;/a&gt;&lt;a name="IDX-124"&gt;&lt;/a&gt;&lt;br /&gt;#Write out error code&lt;br /&gt;movl  ST_ERROR_CODE(%ebp), %ecx&lt;br /&gt;pushl %ecx&lt;br /&gt;call  count_chars&lt;br /&gt;popl  %ecx&lt;br /&gt;movl  %eax, %edx&lt;br /&gt;movl  $STDERR, %ebx&lt;br /&gt;movl  $SYS_WRITE, %eax&lt;br /&gt;int   $LINUX_SYSCALL&lt;br /&gt;&lt;br /&gt;#Write out error message&lt;br /&gt;movl  ST_ERROR_MSG(%ebp), %ecx&lt;br /&gt;pushl %ecx&lt;br /&gt;call  count_chars&lt;br /&gt;popl  %ecx&lt;br /&gt;movl  %eax, %edx&lt;br /&gt;movl  $STDERR, %ebx&lt;br /&gt;movl  $SYS_WRITE, %eax&lt;br /&gt;int   $LINUX_SYSCALL&lt;br /&gt;&lt;br /&gt;pushl $STDERR&lt;br /&gt;call  write_newline&lt;br /&gt;&lt;br /&gt;#Exit with status 1&lt;br /&gt;movl  $SYS_EXIT, %eax&lt;br /&gt;movl  $1, %ebx&lt;br /&gt;int   $LINUX_SYSCALL&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;Enter it in a file called &lt;span class="fixed"&gt;error-exit.s&lt;/span&gt;.  To call it, you just need to push the address of an error message, and then an  error code onto the stack, and call the function.&lt;/p&gt; &lt;p class="para"&gt;Now let's look for potential error spots in our &lt;span class="fixed"&gt;add-year&lt;/span&gt; program. First of all, we don't check to see if  either of our &lt;span class="fixed"&gt;open&lt;/span&gt; system calls actually complete  properly.&lt;/p&gt;&lt;a name="200"&gt;&lt;/a&gt;&lt;a name="IDX-125"&gt;&lt;/a&gt; &lt;p class="para"&gt;Linux returns its status code in &lt;span class="fixed"&gt;%eax&lt;/span&gt;, so  we need to check and see if there is an error.&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt; #Open file for reading&lt;br /&gt;movl  $SYS_OPEN, %eax&lt;br /&gt;movl  $input_file_name, %ebx&lt;br /&gt;movl  $0, %ecx&lt;br /&gt;movl  $0666, %edx&lt;br /&gt;int   $LINUX_SYSCALL&lt;br /&gt;&lt;br /&gt;movl  %eax, INPUT_DESCRIPTOR(%ebp)&lt;br /&gt;&lt;br /&gt;#This will test and see if %eax is&lt;br /&gt;#negative.  If it is not negative, it&lt;br /&gt;#will jump to continue_processing.&lt;br /&gt;#Otherwise it will handle the error&lt;br /&gt;#condition that the negative number&lt;br /&gt;#represents.&lt;br /&gt;cmpl  $0, %eax&lt;br /&gt;jl    continue_processing&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;#Send the error&lt;br /&gt;.section .data&lt;br /&gt;no_open_file_code:&lt;br /&gt;.ascii "0001: \0"&lt;br /&gt;no_open_file_msg:&lt;br /&gt;.ascii "Can't Open Input File\0"&lt;br /&gt;&lt;br /&gt;.section .text&lt;br /&gt;pushl  $no_open_file_msg&lt;br /&gt;pushl  $no_open_file_code&lt;br /&gt;call   error_exit&lt;br /&gt;&lt;br /&gt;continue_processing:&lt;a name="201"&gt;&lt;/a&gt;&lt;a name="IDX-126"&gt;&lt;/a&gt;&lt;br /&gt;#Rest of program&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;So, after calling the system call, we check and see if we have an  error by checking to see if the result of the system call is less than zero. If  so, we call our error reporting and exit routine.&lt;/p&gt; &lt;p class="para"&gt;After every system call, function call, or instruction which can  have erroneous results you should add error checking and handling code.&lt;/p&gt; &lt;p class="para"&gt;To assemble and link the files, do:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;as add-year.s -o add-year.o&lt;br /&gt;as error-exit.s -o error-exit.o&lt;br /&gt;ld add-year.o write-newline.o error-exit.o read-record.o write-&lt;br /&gt;record.o count-chars.o -o add-year&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="last-para"&gt;Now try to run it without the necessary files. It now exits  cleanly and gracefully!&lt;/p&gt;&lt;h2 class="first-section-title"&gt;&lt;a name="202"&gt;&lt;/a&gt;&lt;a name="ch07lev1sec5"&gt;&lt;/a&gt;Review&lt;/h2&gt; &lt;div class="section"&gt; &lt;h3 class="sect3-title"&gt;&lt;a name="203"&gt;&lt;/a&gt;&lt;a name="ch07lev2sec6"&gt;&lt;/a&gt;Know the  Concepts&lt;/h3&gt; &lt;ul class="itemizedlist"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;What are the reasons programmer's have trouble with  scheduling?&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;Find your favorite program, and try to use it in a  completely wrong manner. Open up files of the wrong type, choose invalid  options, close windows that are supposed to be open, etc. Count how many  different error scenarios they had to account for.&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;What are corner cases? Can you list examples of numeric  corner cases?&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;Why is user testing so important?&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;What are stubs and drivers used for? What's the difference  between the two?&lt;/p&gt;&lt;a name="204"&gt;&lt;/a&gt;&lt;a name="IDX-127"&gt;&lt;/a&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;What are recovery points used for?&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;How many different error codes should a program  have?&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt; &lt;div class="section"&gt; &lt;h3 class="sect3-title"&gt;&lt;a name="205"&gt;&lt;/a&gt;&lt;a name="ch07lev2sec7"&gt;&lt;/a&gt;Use the  Concepts&lt;/h3&gt; &lt;ul class="itemizedlist"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;Go through the &lt;span class="fixed"&gt;add-year.s&lt;/span&gt; program  and add error-checking code after every system call.&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;Find one other program we have done so far, and add  error-checking to that program.&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;Add a recovery mechanism for &lt;span class="fixed"&gt;add-year.s&lt;/span&gt; that allows it to read from STDIN if it cannot  open the standard file.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt; &lt;div class="section"&gt; &lt;h3 class="sect3-title"&gt;&lt;a name="206"&gt;&lt;/a&gt;&lt;a name="ch07lev2sec8"&gt;&lt;/a&gt;Going  Further&lt;/h3&gt; &lt;ul class="itemizedlist"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;What, if anything, should you do if your error-reporting  function fails? Why?&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;Try to find bugs in at least one open-source program. File a  bug report for it.&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;Try to fix the bug you found in the previous exercise&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8901974503278002812-6312657414619967438?l=programminggroundup.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://programminggroundup.blogspot.com/feeds/6312657414619967438/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8901974503278002812&amp;postID=6312657414619967438' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8901974503278002812/posts/default/6312657414619967438'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8901974503278002812/posts/default/6312657414619967438'/><link rel='alternate' type='text/html' href='http://programminggroundup.blogspot.com/2007/01/chapter-7-developing-robust-programs.html' title='Chapter 7: Developing Robust Programs'/><author><name>Admin</name><uri>http://www.blogger.com/profile/13783659974416042562</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8901974503278002812.post-5628792128572539134</id><published>2007-01-31T18:09:00.000-08:00</published><updated>2007-01-31T20:17:29.468-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='x86'/><category scheme='http://www.blogger.com/atom/ns#' term='records'/><category scheme='http://www.blogger.com/atom/ns#' term='asm'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='assembly language'/><title type='text'>Chapter 6: Reading and Writing Simple Records</title><content type='html'>&lt;div class="section"&gt; &lt;h2 class="sect2-title"&gt;&lt;a name="152"&gt;&lt;/a&gt;Overview&lt;/h2&gt;&lt;a name="153"&gt;&lt;/a&gt;&lt;a name="IDX-95"&gt;&lt;/a&gt; &lt;p class="para"&gt;As mentioned in &lt;span class="chapterjump"&gt;Chapter 5&lt;/span&gt;, many applications deal with data that is &lt;i class="emphasis"&gt;persistent -&lt;/i&gt; meaning that the data lives longer than the  program by being stored on disk in files. You can shut down the program and open  it back up, and you are back where you started. Now, there are two basic kinds  of persistent data - structured and unstructured. Unstructured data is like what  we dealt with in the &lt;span class="fixed"&gt;toupper&lt;/span&gt; program. It just dealt  with text files that were entered by a person. The contents of the files weren't  usable by a program because a program can't interpret what the user is trying to  say in random text.&lt;/p&gt; &lt;p class="para"&gt;Structured data, on the other hand, is what computers excel at  handling. Structured data is data that is divided up into fields and records.  For the most part, the fields and records are fixed-length. Because the data is  divided into fixed-length records and fixed-format fields, the computer can  interpret the data. Structured data can contain variable-length fields, but at  that point you are usually better off with a database.&lt;sup&gt;[&lt;a href="http://www2.blogger.com/post-edit.g?blogID=8901974503278002812&amp;postID=5628792128572539134#ftn.N34" name="N34"&gt;1&lt;/a&gt;]&lt;/sup&gt; &lt;/p&gt; &lt;div class="highlights"&gt; &lt;p class="first-para"&gt;This chapter deals with reading and writing simple  fixed-length records. Let's say we wanted to store some basic information about  people we know. We could imagine the following example fixed-length record about  people:&lt;/p&gt; &lt;ul class="itemizedlist"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;Firstname - 40 bytes&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;Lastname - 40 bytes&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;Address - 240 bytes&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;Age - 4 bytes&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p class="para"&gt;&lt;a name="154"&gt;&lt;/a&gt;&lt;a name="IDX-96"&gt;&lt;/a&gt;In this, everything is  character data except for the age, which is simply a numeric field, using a  standard 4-byte word (we could just use a single byte for this, but keeping it  at a word makes it easier to process).&lt;/p&gt; &lt;p class="para"&gt;In programming, you often have certain definitions that you will  use over and over again within the program, or perhaps within several programs.  It is good to separate these out into files that are simply included into the  assembly language files as needed. For example, in our next programs we will  need to access the different parts of the record above. This means we need to  know the offsets of each field from the beginning of the record in order to  access them using base pointer addressing. The following constants describe the  offsets to the above structure. Put them in a file named &lt;span class="fixed"&gt;record-def.s:&lt;/span&gt; &lt;/p&gt; &lt;p class="para"&gt; &lt;/p&gt;&lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt; .equ RECORD_FIRSTNAME, 0&lt;br /&gt;.equ RECORD_LASTNAME, 40&lt;br /&gt;.equ RECORD_ADDRESS, 80&lt;br /&gt;.equ RECORD_AGE, 320&lt;br /&gt;&lt;br /&gt;.equ RECORD_SIZE, 324&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;  &lt;p class="para"&gt;In addition, there are several constants that we have been  defining over and over in our programs, and it is useful to put them in a file,  so that we don't have to keep entering them. Put the following constants in a  file called &lt;span class="fixed"&gt;linux.s:&lt;/span&gt; &lt;/p&gt; &lt;p class="para"&gt; &lt;/p&gt;&lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt; #Common Linux Definitions&lt;br /&gt;&lt;br /&gt;#System Call Numbers&lt;br /&gt;.equ SYS_EXIT, 1&lt;br /&gt;.equ SYS_READ, 3&lt;br /&gt;.equ SYS_WRITE, 4&lt;br /&gt;.equ SYS_OPEN, 5&lt;br /&gt;.equ SYS_CLOSE, 6&lt;br /&gt;.equ SYS_BRK, 45&lt;a name="155"&gt;&lt;/a&gt;&lt;a name="IDX-97"&gt;&lt;/a&gt;&lt;br /&gt;#System Call Interrupt Number&lt;br /&gt;.equ LINUX_SYSCALL, 0x80&lt;br /&gt;&lt;br /&gt;#Standard File Descriptors&lt;br /&gt;.equ STDIN, 0&lt;br /&gt;.equ STDOUT, 1&lt;br /&gt;.equ STDERR, 2&lt;br /&gt;&lt;br /&gt;#Common Status Codes&lt;br /&gt;.equ END_OF_FILE, 0&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;  &lt;p class="para"&gt;We will write three programs in this chapter using the structure  defined in &lt;span class="fixed"&gt;record-def.s.&lt;/span&gt; The first program will build a  file containing several records as defined above. The second program will  display the records in the file. The third program will add 1 year to the age of  every record.&lt;/p&gt; &lt;p class="para"&gt;In addition to the standard constants we will be using throughout  the programs, there are also two functions that we will be using in several of  the programs - one which reads a record and one which writes a record.&lt;/p&gt; &lt;p class="para"&gt;What parameters do these functions need in order to operate? We  basically need:&lt;/p&gt; &lt;ul class="itemizedlist"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;The location of a buffer that we can read a record into&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;The file descriptor that we want to read from or write  to&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p class="para"&gt;Let's look at our reading function first:&lt;/p&gt; &lt;p class="para"&gt; &lt;/p&gt;&lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt; .include "record-def.s"&lt;br /&gt;.include "linux.s"&lt;br /&gt;&lt;br /&gt;#PURPOSE:   This function reads a record from the file&lt;a name="156"&gt;&lt;/a&gt;&lt;a name="IDX-98"&gt;&lt;/a&gt;&lt;br /&gt;#          descriptor&lt;br /&gt;#&lt;br /&gt;#INPUT:    The file descriptor and a buffer&lt;br /&gt;#&lt;br /&gt;#OUTPUT:   This function writes the data to the buffer&lt;br /&gt;#          and returns a status code.&lt;br /&gt;#&lt;br /&gt;#STACK LOCAL VARIABLES&lt;br /&gt;.equ ST_READ_BUFFER, 8&lt;br /&gt;.equ ST_FILEDES, 12&lt;br /&gt;.section .text&lt;br /&gt;.globl read_record&lt;br /&gt;.type read_record, @function&lt;br /&gt;read_record:&lt;br /&gt;pushl %ebp&lt;br /&gt;movl  %esp, %ebp&lt;br /&gt;&lt;br /&gt;pushl %ebx&lt;br /&gt;movl  ST_FILEDES(%ebp), %ebx&lt;br /&gt;movl  ST_READ_BUFFER(%ebp), %ecx&lt;br /&gt;movl  $RECORD_SIZE, %edx&lt;br /&gt;movl  $SYS_READ, %eax&lt;br /&gt;int   $LINUX_SYSCALL&lt;br /&gt;&lt;br /&gt;#NOTE - %eax has the return value, which we will&lt;br /&gt;#       give back to our calling program&lt;br /&gt;popl  %ebx&lt;br /&gt;&lt;br /&gt;movl  %ebp, %esp&lt;br /&gt;popl  %ebp&lt;br /&gt;ret&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;  &lt;p class="para"&gt;It's a pretty simply function. It just reads data the size of our  structure into an appropriately sized buffer from the given file descriptor. The  writing one is similar:&lt;/p&gt; &lt;p class="para"&gt; &lt;/p&gt;&lt;div class="informalexample"&gt;&lt;a name="157"&gt;&lt;/a&gt;&lt;a name="IDX-99"&gt;&lt;/a&gt;&lt;pre class="literallayout"&gt; .include "linux.s"&lt;br /&gt;.include "record-def.s"&lt;br /&gt;#PURPOSE:   This function writes a record to&lt;br /&gt;#           the given file descriptor&lt;br /&gt;#&lt;br /&gt;#INPUT:     The file descriptor and a buffer&lt;br /&gt;#&lt;br /&gt;#OUTPUT:    This function produces a status code&lt;br /&gt;#&lt;br /&gt;#STACK LOCAL VARIABLES&lt;br /&gt;.equ ST_WRITE_BUFFER, 8&lt;br /&gt;.equ ST_FILEDES, 12&lt;br /&gt;.section .text&lt;br /&gt;.globl write_record&lt;br /&gt;.type write_record, @function&lt;br /&gt;write_record:&lt;br /&gt;pushl %ebp&lt;br /&gt;movl  %esp, %ebp&lt;br /&gt;&lt;br /&gt;pushl %ebx&lt;br /&gt;movl  $SYS_WRITE, %eax&lt;br /&gt;movl  ST_FILEDES(%ebp), %ebx&lt;br /&gt;movl  ST_WRITE_BUFFER(%ebp), %ecx&lt;br /&gt;movl  $RECORD_SIZE, %edx&lt;br /&gt;int   $LINUX_SYSCALL&lt;br /&gt;&lt;br /&gt;#NOTE - %eax has the return value, which we will&lt;br /&gt;#       give back to our calling program&lt;br /&gt;popl  %ebx&lt;br /&gt;&lt;br /&gt;movl  %ebp, %esp&lt;br /&gt;popl  %ebp&lt;br /&gt;ret&lt;br /&gt;&lt;a name="158"&gt;&lt;/a&gt;&lt;a name="IDX-100"&gt;&lt;/a&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;  &lt;p class="last-para"&gt;Now that we have our basic definitions down, we are ready to  write our programs.&lt;/p&gt;&lt;/div&gt;&lt;/div&gt; &lt;div class="footnotes"&gt; &lt;div class="footnote"&gt; &lt;p&gt;&lt;sup&gt;[&lt;a href="http://www2.blogger.com/post-edit.g?blogID=8901974503278002812&amp;amp;postID=5628792128572539134#N34" name="ftn.N34"&gt;1&lt;/a&gt;]&lt;/sup&gt;A database is a program which  handles persistent structured data for you. You don't have to write the programs  to read and write the data to disk, to do lookups, or even to do basic  processing. It is a very high-level interface to structured data which, although  it adds some overhead and additional complexity, is very useful for complex data  processing tasks. References for learning how databases work are listed in  Chapter 13.&lt;/p&gt;&lt;h2 class="first-section-title"&gt;&lt;a name="159"&gt;&lt;/a&gt;&lt;a name="ch06lev1sec1"&gt;&lt;/a&gt;Writing  Records&lt;/h2&gt; &lt;p class="first-para"&gt;This program will simply write some hardcoded records to  disk. It will:&lt;/p&gt; &lt;ul class="itemizedlist"&gt;&lt;li class="first-listitem"&gt; &lt;p class="first-para"&gt;Open the file&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;Write three records&lt;/p&gt; &lt;/li&gt;&lt;li class="listitem"&gt; &lt;p class="first-para"&gt;Close the file&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p class="para"&gt;Type the following code into a file called &lt;span class="fixed"&gt;write-records.s:&lt;/span&gt; &lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt; .include "linux.s"&lt;br /&gt;.include "record-def.s"&lt;br /&gt;&lt;br /&gt;.section .data&lt;br /&gt;&lt;br /&gt;#Constant data of the records we want to write&lt;br /&gt;#Each text data item is padded to the proper&lt;br /&gt;#length with null (i.e. 0) bytes.&lt;br /&gt;&lt;br /&gt;#.rept is used to pad each item.  .rept tells&lt;br /&gt;#the assembler to repeat the section between&lt;br /&gt;#.rept and .endr the number of times specified.&lt;br /&gt;#This is used in this program to add extra null&lt;br /&gt;#characters at the end of each field to fill&lt;br /&gt;#it up&lt;br /&gt;record1:&lt;br /&gt;.ascii "Fredrick\0"&lt;br /&gt;.rept 31 #Padding to 40 bytes&lt;br /&gt;.byte 0&lt;br /&gt;.endr&lt;br /&gt;&lt;br /&gt;.ascii "Bartlett\0"&lt;a name="160"&gt;&lt;/a&gt;&lt;a name="IDX-101"&gt;&lt;/a&gt;&lt;br /&gt;.rept 31 #Padding to 40 bytes&lt;br /&gt;.byte 0&lt;br /&gt;.endr&lt;br /&gt;&lt;br /&gt;.ascii "4242 S Prairie\nTulsa, OK 55555\0"&lt;br /&gt;.rept 209 #Padding to 240 bytes&lt;br /&gt;.byte 0&lt;br /&gt;.endr&lt;br /&gt;&lt;br /&gt;.long 45&lt;br /&gt;&lt;br /&gt;record2:&lt;br /&gt;.ascii "Marilyn\0"&lt;br /&gt;.rept 32 #Padding to 40 bytes&lt;br /&gt;.byte 0&lt;br /&gt;.endr&lt;br /&gt;&lt;br /&gt;.ascii "Taylor\0"&lt;br /&gt;.rept 33 #Padding to 40 bytes&lt;br /&gt;.byte 0&lt;br /&gt;.endr&lt;br /&gt;&lt;br /&gt;.ascii "2224 S Johannan St\nChicago, IL 12345\0"&lt;br /&gt;.rept 203 #Padding to 240 bytes&lt;br /&gt;.byte 0&lt;br /&gt;.endr&lt;br /&gt;&lt;br /&gt;.long 29&lt;br /&gt;&lt;br /&gt;record3:&lt;br /&gt;.ascii "Derrick\0"&lt;br /&gt;.rept 32 #Padding to 40 bytes&lt;br /&gt;.byte 0&lt;br /&gt;.endr&lt;a name="161"&gt;&lt;/a&gt;&lt;a name="IDX-102"&gt;&lt;/a&gt;&lt;br /&gt;.ascii "McIntire\0"&lt;br /&gt;.rept 31 #Padding to 40 bytes&lt;br /&gt;.byte 0&lt;br /&gt;.endr&lt;br /&gt;&lt;br /&gt;.ascii "500 W Oakland\nSan Diego, CA 54321\0"&lt;br /&gt;.rept 206 #Padding to 240 bytes&lt;br /&gt;.byte 0&lt;br /&gt;.endr&lt;br /&gt;&lt;br /&gt;.long 36&lt;br /&gt;&lt;br /&gt;#This is the name of the file we will write to&lt;br /&gt;file_name:&lt;br /&gt;.ascii "test.dat\0"&lt;br /&gt;&lt;br /&gt;.equ ST_FILE_DESCRIPTOR, -4&lt;br /&gt;.globl _start&lt;br /&gt;_start:&lt;br /&gt;#Copy the stack pointer to %ebp&lt;br /&gt;movl %esp, %ebp&lt;br /&gt;#Allocate space to hold the file descriptor&lt;br /&gt;subl $4, %esp&lt;br /&gt;&lt;br /&gt;#Open the file&lt;br /&gt;movl  $SYS_OPEN, %eax&lt;br /&gt;movl  $file_name, %ebx&lt;br /&gt;movl  $0101, %ecx #This says to create if it&lt;br /&gt;                 #doesn't exist, and open for&lt;br /&gt;                 #writing&lt;br /&gt;movl  $0666, %edx&lt;br /&gt;int   $LINUX_SYSCALL&lt;br /&gt;&lt;br /&gt;#Store the file descriptor away&lt;br /&gt;movl  %eax, ST_FILE_DESCRIPTOR(%ebp)&lt;a name="162"&gt;&lt;/a&gt;&lt;a name="IDX-103"&gt;&lt;/a&gt;&lt;br /&gt;#Write the first record&lt;br /&gt;pushl ST_FILE_DESCRIPTOR(%ebp)&lt;br /&gt;pushl $recordl&lt;br /&gt;call  write_record&lt;br /&gt;addl  $8, %esp&lt;br /&gt;&lt;br /&gt;#Write the second record&lt;br /&gt;pushl ST_FILE_DESCRIPTOR(%ebp)&lt;br /&gt;pushl $record2&lt;br /&gt;call  write_record&lt;br /&gt;addl  $8, %esp&lt;br /&gt;&lt;br /&gt;#Write the third record&lt;br /&gt;pushl ST_FILE_DESCRIPTOR(%ebp)&lt;br /&gt;pushl $record3&lt;br /&gt;call  write_record&lt;br /&gt;addl  $8, %esp&lt;br /&gt;&lt;br /&gt;#Close the file descriptor&lt;br /&gt;movl  $SYS_CLOSE, %eax&lt;br /&gt;movl  ST_FILE_DESCRIPTOR(%ebp), %ebx&lt;br /&gt;int   $LINUX_SYSCALL&lt;br /&gt;&lt;br /&gt;#Exit the program&lt;br /&gt;movl  $SYS_EXIT, %eax&lt;br /&gt;movl  $0, %ebx&lt;br /&gt;int   $LINUX_SYSCALL&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;This is a fairly simple program. It merely consists of defining  the data we want to write in the . &lt;span class="fixed"&gt;data&lt;/span&gt; section, and  then calling the right system calls and function calls to accomplish it. For a  refresher of all of the system calls used, see &lt;span class="chapterjump"&gt;Appendix C&lt;/span&gt;.&lt;/p&gt;&lt;a name="163"&gt;&lt;/a&gt;&lt;a name="IDX-104"&gt;&lt;/a&gt; &lt;p class="para"&gt;You may have noticed the lines:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt; .include "linux.s"&lt;br /&gt;.include "record-def.s"&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;These statements cause the given files to basically be pasted  right there in the code. You don't need to do this with functions, because the  linker can take care of combining functions exported with .&lt;span class="fixed"&gt;globl&lt;/span&gt;. However, constants defined in another file do need to  be imported in this way.&lt;/p&gt; &lt;p class="para"&gt;Also, you may have noticed the use of a new assembler directive,  .&lt;span class="fixed"&gt;rept.&lt;/span&gt; This directive repeats the contents of the file  between the .&lt;span class="fixed"&gt;rept&lt;/span&gt; and the .&lt;span class="fixed"&gt;endr&lt;/span&gt; directives the number of times specified after .&lt;span class="fixed"&gt;rept.&lt;/span&gt; This is usually used the way we used it - to pad values  in the . &lt;span class="fixed"&gt;data&lt;/span&gt; section. In our case, we are adding null  characters to the end of each field until they are their defined lengths.&lt;/p&gt; &lt;p class="para"&gt;To build the application, run the commands:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;as write-records.s -o write-record.o&lt;br /&gt;as write-record.s -o write-record.o&lt;br /&gt;ld write-record.o write-records.o -o write-records&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="para"&gt;Here we are assembling two files separately, and then combining  them together using the linker. To run the program, just type the following:&lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre class="literallayout"&gt;./write-records&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="last-para"&gt;This will cause a file called &lt;span class="fixed"&gt;test.dat&lt;/span&gt; to be created containing the records. However, since  they contain non-printable characters (the null character, specifically), they  may not be viewable by a text editor. Therefore we need the next program to read  them for us.&lt;/p&gt;&lt;div class="section"&gt; &lt;h2 class="first-section-title"&gt;&lt;a name="164"&gt;&lt;/a&gt;&lt;a name="ch06lev1sec2"&gt;&lt;/a&gt;Reading  Records&lt;/h2&gt;&lt;a name="165"&gt;&lt;/a&gt;&lt;a name="IDX-105"&gt;&lt;/a&gt; &lt;p class="para"&gt;Now we will consider the process of reading records. In this  program, we will read each record and display the first name listed with each  record.&lt;/p&gt; &lt;p class="para"&gt;Since each person's name is a different length, we will need a  function to count the number of characters we want to write. Since we pad each  field with null characters, we can simply count characters until we reach a null  character.&lt;sup&gt;[&lt;a href="http://www2.blogger.com/post-edit.g?blogID=8901974503278002812&amp;postID=5628792128572539134#ftn.N21" name="N21"&gt;2&lt;/a&gt;]&lt;/sup&gt; Note that this means  our records must contain at least one null character each.&lt;/p&gt; &lt;p class="para"&gt;Here is the code. Put it in a file called &lt;span class="fixed"&gt;count-chars.s:&lt;/span&gt; &lt;/p&gt; &lt;div class="informalexample"&gt;&lt;pre c
