tag:blogger.com,1999:blog-89019745032780028122009-03-31T04:52:58.595-07:00Programming from the Ground UpAn introduction to programming using linux assembly languageAdminhttp://www.blogger.com/profile/13783659974416042562noreply@blogger.comBlogger23125tag:blogger.com,1999:blog-8901974503278002812.post-88736295588606600772099-01-30T22:48:00.000-08:002007-01-31T23:25:40.101-08:00Chapter 1: Introduction<div class="section"> <h2 class="sect2-title"><a name="13"></a><a name="ch01lev1sec1"></a>Welcome to Programming</h2> <p class="first-para">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.</p> <p class="para">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.</p> <p class="para">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:</p><a name="14"></a><a name="IDX-2"></a> <ul class="itemizedlist"><li class="first-listitem"> <p class="first-para">Understand how a program works and interacts with other programs</p> </li><li class="listitem"> <p class="first-para">Read other people's programs and learn how they work</p> </li><li class="listitem"> <p class="first-para">Learn new programming languages quickly</p> </li><li class="listitem"> <p class="first-para">Learn advanced concepts in computer science quickly</p></li></ul> <p class="para">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.</p> <p class="para">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.</p> <p class="para">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.</p><a name="15"></a><a name="IDX-3"></a> <p class="para">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 <<a href="mailto:pgubook-readers@nongnu.org"><span class="fixed">pgubook-readers@nongnu.org</span></a>>. 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 <a class="url" href="http://mail.nongnu.org/mailman/listinfo/pgubook-readers" target="_top">http://mail.nongnu.org/mailman/listinfo/pgubook-readers</a>.</p> <p class="last-para">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 <a class="url" href="http://www.k12linux.org/" target="_top">http://www.k12linux.org/</a> and they have a helpful and responsive mailing list available.</p><div class="chapter"><a name="ch01"></a> <div class="section"> <h2 class="first-section-title"><a name="16"></a><a name="ch01lev1sec2"></a>Your Tools</h2> <p class="first-para">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 <a class="url" href="http://rute.sourceforge.net/" target="_top">http://rute.sourceforge.net/</a> <sup>[<a href="http://www2.blogger.com/post-edit.g?blogID=8901974503278002812&postID=8873629558860660077#ftn.N19" name="N19">1</a>]</sup> 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.</p> <p class="para">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 <a class="url" href="http://www.linux.org/groups/" target="_top">http://www.linux.org/groups/</a> </p> <p class="para">All of these programs have been tested using Red Hat Linux 8.0, and should work with any other GNU/Linux distribution, too. <sup>[<a href="http://www2.blogger.com/post-edit.g?blogID=8901974503278002812&postID=8873629558860660077#ftn.N44" name="N44">2</a>]</sup> They will not work with non-Linux <a name="17"></a><a name="IDX-4"></a>operating systems such as BSD or other systems. However, all of the <i class="emphasis">skills</i> learned in this book should be easily transferable to any other system.</p> <p class="para">If you do not have access to a GNU/Linux machine, you can look for a hosting provider who offers a Linux <i class="emphasis">shell account,</i> 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 <span class="fixed">start</span>, then <span class="fixed">run</span>, then type in <span class="fixed">telnet</span>. However, it is usually better to download PuTTY from <a class="url" href="http://www.chiart.greenend.co.uk/%7Esgtatham/putty/" target="_top">http://www.chiart.greenend.co.uk/~sgtatham/putty/</a> because Windows' telnet has some weird problems. There are a lot of options for the Macintosh, too. NiftyTelnet is my favorite.</p> <p class="para">If you don't have GNU/Linux and can't find a shell account service, then you can download Knoppix from <a class="url" href="http://www.knoppix.org/" target="_top">http://www.knoppix.org/</a> 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.</p> <p class="para">So what is GNU/Linux? GNU/Linux is an operating system modeled after UNIX®. The GNU part comes from the GNU Project (<a class="url" href="http://www.gnu.org/" target="_top">http://www.gnu.org/</a>) <sup>[<a href="http://www2.blogger.com/post-edit.g?blogID=8901974503278002812&postID=8873629558860660077#ftn.N91" name="N91">3</a>]</sup>, 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.</p> <p class="para">Linux is the name of the <i class="emphasis">kernel.</i> 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 <a name="18"></a><a name="IDX-5"></a>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 <i class="emphasis">scancodes</i> 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.</p> <div class="example"><span class="example-title"><span class="example-titlelabel">Example 1-1: </span>How the computer processes keyboard sigals</span><a name="19"></a><a name="ch01ex01"></a> <div class="formalbody"> <table class="BlueLine" border="0" cellpadding="0" cellspacing="0" width="100%"> <tbody> <tr> <td class="bluecell" bg="" style="color: rgb(0, 0, 128);"><span style="color: rgb(1, 1, 0);font-family:Arial;font-size:85%;" ><b><img alt="Start example" src="http://www2.blogger.com/_.gif" border="0" height="2" width="1" /></b></span></td></tr></tbody></table> <div class="informalexample"><pre class="literallayout">Keyboard -> Kernel -> Windowing system -> Application program<br /></pre></div> <table class="BlueLine" border="0" cellpadding="0" cellspacing="0" width="100%"> <tbody> <tr> <td class="bluecell" bg="" style="color: rgb(0, 0, 128);"><span style="color: rgb(1, 1, 0);font-family:Arial;font-size:85%;" ><b><img alt="End example" src="http://www2.blogger.com/_.gif" border="0" height="2" width="1" /></b></span></td></tr></tbody></table> <table class="BlankSpace" border="0" cellpadding="0" cellspacing="0" width="100%"> <tbody> <tr> <td height="16"><br /></td></tr></tbody></table></div></div> <p class="para">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.</p> <p class="para">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.</p> <p class="para">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.</p> <p class="para">For the most part, this book will be using the computer's low-level assembly language. There are essentially three kinds of languages:</p><a name="20"></a><a name="IDX-6"></a> <p class="para">Machine Language</p> <ul class="simple-list"><li class="first-listitem"> <p class="first-para">This is what the computer actually sees and deals with. Every command the computer sees is given as a number or sequence of numbers.</p></li></ul> <p class="para">Assembly Language</p> <ul class="simple-list"><li class="first-listitem"> <p class="first-para">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.</p></li></ul> <p class="para">High-Level Language</p> <ul class="simple-list"><li class="first-listitem"> <p class="first-para">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.</p></li></ul> <p class="last-para">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.</p></div> <div class="footnotes"> <div class="footnote"> <p><sup>[<a href="http://www2.blogger.com/post-edit.g?blogID=8901974503278002812&postID=8873629558860660077#N19" name="ftn.N19">1</a>]</sup>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 <span class="fixed">pico</span>, <span class="fixed">emacs</span>, or <span class="fixed">vi</span> (or others).</p></div> <div class="footnote"> <p><sup>[<a href="http://www2.blogger.com/post-edit.g?blogID=8901974503278002812&postID=8873629558860660077#N44" name="ftn.N44">2</a>]</sup>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.</p></div> <div class="footnote"> <p><sup>[<a href="http://www2.blogger.com/post-edit.g?blogID=8901974503278002812&postID=8873629558860660077#N91" name="ftn.N91">3</a>]</sup>The GNU Project is a project by the Free Software Foundation to produce a complete, free operating system.</p></div></div></div></div><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8901974503278002812-8873629558860660077?l=programminggroundup.blogspot.com'/></div>Adminhttp://www.blogger.com/profile/13783659974416042562noreply@blogger.com1tag:blogger.com,1999:blog-8901974503278002812.post-18350000852119239642007-01-31T21:48:00.000-08:002007-01-31T21:50:23.060-08:00Programming from the Ground Up<div class="authorgroup"> <div class="author">Jonathan Bartlett</div> <div class="author">Edited by Dominick Bruno, Jr.</div></div> <p class="copyright">Copyright © <i class="emphasis"><a name="4"></a><a name="IDX-ii"></a></i>2004 by Jonathan Bartlett</p> <div class="legalnotice"> <p class="first-para">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 <span class="chapterjump">Appendix H</span>. In addition, you are granted full rights to use the code examples for any purpose without even having to credit the authors.</p> <p class="first-para">To receive a copy of this book in electronic form, please visit the website <a class="url" href="http://savannah.nongnu.org/projects/pgubook/" target="_top">http://savannah.nongnu.org/projects/pgubook/</a> This site contains the instructions for downloading a transparent copy of this book as defined by the GNU Free Documentation License.</p> <p class="first-para">All trademarks are property of their respective owners.</p></div><span class="isbn">ISBN 0-9752838-4-7<br /></span> <div class="legalnotice"> <p class="first-para">Published by Bartlett Publishing in Broken Arrow, Oklahom</p> <p class="first-para">Library of Congress Control Number: 2004091465</p> <p class="first-para">Bartlett Publishing Cataloging-in-Publication Data</p> <p class="first-para"> </p><div class="informalexample"><pre class="literallayout-normal">Bartlett, Jonathan, 1977-<br /> Programming from the ground up / Jonathan Bartlett ; edited by Dominick<br /> Bruno.<br /> p. cm.<br /> Includes index.<br /></pre></div> <p class="first-para">ISBN 0-9752838-4-7</p></div><br /><div class="subjectset"><span class="subject"><span class="subjectterm">1. Linux.</span></span> <span class="subject"><span class="subjectterm">2. Operating systems (Computers)</span></span> <span class="subject"><span class="subjectterm">3. Computer programming.</span></span> <span class="subject"><span class="subjectterm">I. Bruno, Dominick.</span></span> <span class="subject"><span class="subjectterm">II. Title.</span></span> </div> <div class="legalnotice"> <p class="first-para">QA76.76.O63 2004</p> <p class="first-para">005.268—dc22 2004091465<a name="5"></a><a name="IDX-iii"></a> </p> <p class="first-para">This book can be purchased at <a class="url" href="http://www.bartlettpublishing.com/" target="_top">http://www.bartlettpublishing.com/</a> </p> <p class="first-para">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.</p></div><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8901974503278002812-1835000085211923964?l=programminggroundup.blogspot.com'/></div>Adminhttp://www.blogger.com/profile/13783659974416042562noreply@blogger.com3tag:blogger.com,1999:blog-8901974503278002812.post-27220555002750184572007-01-31T19:56:00.000-08:002007-01-31T19:58:25.699-08:00Appendix I: Personal Dedication<p class="para">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.</p> <p class="para">There are some people, however, that I would like to thank specifically.</p> <p class="para">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.</p> <p class="para">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.</p> <p class="para">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.</p> <p class="para">I also want to thanks the Little Light House school. My entire family is continually blessed by the help you give to our son.</p> <p class="para">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.</p><a name="505"></a><a name="IDX-312"></a> <p class="last-para">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.</p><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8901974503278002812-2722055500275018457?l=programminggroundup.blogspot.com'/></div>Adminhttp://www.blogger.com/profile/13783659974416042562noreply@blogger.com0tag:blogger.com,1999:blog-8901974503278002812.post-36148316361237565372007-01-31T19:55:00.000-08:002007-01-31T19:56:28.938-08:00Appendix H: GNU Free Documentation License<p class="para"><span class="fixed">0. PREAMBLE</span> </p> <p class="para">The purpose of this License is to make a manual, textbook, or other written document "free" in the sense of freedom: to assure everyone the effective freedom to copy and redistribute it, with or without modifying it, either commercially or noncommercially. Secondarily, this License preserves for the author and publisher a way to get credit for their work, while not being considered responsible for modifications made by others.</p> <p class="para">This License is a kind of "copyleft", which means that derivative works of the document must themselves be free in the same sense. It complements the GNU General Public License, which is a copyleft license designed for free software.</p> <p class="para">We have designed this License in order to use it for manuals for free software, because free software needs free documentation: a free program should come with manuals providing the same freedoms that the software does. But this License is not limited to software manuals; it can be used for any textual work, regardless of subject matter or whether it is published as a printed book. We recommend this License principally for works whose purpose is instruction or reference.</p> <p class="para"><span class="fixed">1. APPLICABILITY AND DEFINITIONS</span> </p> <p class="para">This License applies to any manual or other work that contains a notice placed by the copyright holder saying it can be distributed under the terms of this License. The "Document", below, refers to any such manual or work. Any member of the public is a licensee, and is addressed as "you".</p> <p class="para">A "Modified Version" of the Document means any work containing the Document or a portion of it, either copied verbatim, or with modifications and/or translated into another language.</p> <p class="para">A "Secondary Section" is a named appendix or a front-matter section of the Document that deals exclusively with the relationship of the publishers or authors of the Document to the Document's overall subject (or to related matters) and <a name="494"></a><a name="IDX-302"></a>contains nothing that could fall directly within that overall subject. (For example, if the Document is in part a textbook of mathematics, a Secondary Section may not explain any mathematics.) The relationship could be a matter of historical connection with the subject or with related matters, or of legal, commercial, philosophical, ethical or political position regarding them.</p> <p class="para">The "Invariant Sections" are certain Secondary Sections whose titles are designated, as being those of Invariant Sections, in the notice that says that the Document is released under this License.</p> <p class="para">The "Cover Texts" are certain short passages of text that are listed, as Front-Cover Texts or Back-Cover Texts, in the notice that says that the Document is released under this License.</p> <p class="para">A "Transparent" copy of the Document means a machine-readable copy, represented in a format whose specification is available to the general public, whose contents can be viewed and edited directly and straightforwardly with generic text editors or (for images composed of pixels) generic paint programs or (for drawings) some widely available drawing editor, and that is suitable for input to text formatters or for automatic translation to a variety of formats suitable for input to text formatters. A copy made in an otherwise Transparent file format whose markup has been designed to thwart or discourage subsequent modification by readers is not Transparent. A copy that is not "Transparent" is called "Opaque".</p> <p class="para">Examples of suitable formats for Transparent copies include plain ASCII without markup, Texinfo input format, LaTeX input format, SGML or XML using a publicly available DTD, and standard-conforming simple HTML designed for human modification. Opaque formats include PostScript, PDF, proprietary formats that can be read and edited only by proprietary word processors, SGML or XML for which the DTD and/or processing tools are not generally available, and the machine-generated HTML produced by some word processors for output purposes only.</p> <p class="para">The "Title Page" means, for a printed book, the title page itself, plus such following pages as are needed to hold, legibly, the material this License requires to <a name="495"></a><a name="IDX-303"></a>appear in the title page. For works in formats which do not have any title page as such, "Title Page" means the text near the most prominent appearance of the work's title, preceding the beginning of the body of the text.</p> <p class="para"><span class="fixed">2. VERBATIM COPYING</span> </p> <p class="para">You may copy and distribute the Document in any medium, either commercially or noncommercially, provided that this License, the copyright notices, and the license notice saying this License applies to the Document are reproduced in all copies, and that you add no other conditions whatsoever to those of this License. You may not use technical measures to obstruct or control the reading or further copying of the copies you make or distribute. However, you may accept compensation in exchange for copies. If you distribute a large enough number of copies you must also follow the conditions in section 3.</p> <p class="para">You may also lend copies, under the same conditions stated above, and you may publicly display copies.</p> <p class="para"><span class="fixed">3. COPYING IN QUANTITY</span> </p> <p class="para">If you publish printed copies of the Document numbering more than 100, and the Document's license notice requires Cover Texts, you must enclose the copies in covers that carry, clearly and legibly, all these Cover Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on the back cover. Both covers must also clearly and legibly identify you as the publisher of these copies. The front cover must present the full title with all words of the title equally prominent and visible. You may add other material on the covers in addition. Copying with changes limited to the covers, as long as they preserve the title of the Document and satisfy these conditions, can be treated as verbatim copying in other respects.</p> <p class="para">If the required texts for either cover are too voluminous to fit legibly, you should put the first ones listed (as many as fit reasonably) on the actual cover, and continue the rest onto adjacent pages.</p> <p class="para">If you publish or distribute Opaque copies of the Document numbering more than 100, you must either include a machine-readable Transparent copy along with <a name="496"></a><a name="IDX-304"></a>each Opaque copy, or state in or with each Opaque copy a publicly-accessible computer-network location containing a complete Transparent copy of the Document, free of added material, which the general network-using public has access to download anonymously at no charge using public-standard network protocols. If you use the latter option, you must take reasonably prudent steps, when you begin distribution of Opaque copies in quantity, to ensure that this Transparent copy will remain thus accessible at the stated location until at least one year after the last time you distribute an Opaque copy (directly or through your agents or retailers) of that edition to the public.</p> <p class="para">It is requested, but not required, that you contact the authors of the Document well before redistributing any large number of copies, to give them a chance to provide you with an updated version of the Document.</p> <p class="para"><span class="fixed">4. MODIFICATIONS</span> </p> <p class="para">You may copy and distribute a Modified Version of the Document under the conditions of sections 2 and 3 above, provided that you release the Modified Version under precisely this License, with the Modified Version filling the role of the Document, thus licensing distribution and modification of the Modified Version to whoever possesses a copy of it. In addition, you must do these things in the Modified Version:</p> <ul class="itemizedlist"><li class="first-listitem"> <p class="first-para"><b class="bold">A.</b> Use in the Title Page (and on the covers, if any) a title distinct from that of the Document, and from those of previous versions (which should, if there were any, be listed in the History section of the Document). You may use the same title as a previous version if the original publisher of that version gives permission.</p> </li><li class="listitem"> <p class="first-para"><b class="bold">B.</b> List on the Title Page, as authors, one or more persons or entities responsible for authorship of the modifications in the Modified Version, together with at least five of the principal authors of the Document (all of its principal authors, if it has less than five).</p><a name="497"></a><a name="IDX-305"></a> </li><li class="listitem"> <p class="first-para"><b class="bold">C.</b> State on the Title Page the name of the publisher of the Modified Version, as the publisher.</p> </li><li class="listitem"> <p class="first-para"><b class="bold">D.</b> Preserve all the copyright notices of the Document.</p> </li><li class="listitem"> <p class="first-para"><b class="bold">E.</b> Add an appropriate copyright notice for your modifications adjacent to the other copyright notices.</p> </li><li class="listitem"> <p class="first-para"><b class="bold">F.</b> Include, immediately after the copyright notices, a license notice giving the public permission to use the Modified Version under the terms of this License, in the form shown in the Addendum below.</p> </li><li class="listitem"> <p class="first-para"><b class="bold">G.</b> Preserve in that license notice the full lists of Invariant Sections and required Cover Texts given in the Document's license notice.</p> </li><li class="listitem"> <p class="first-para"><b class="bold">H.</b> Include an unaltered copy of this License.</p> </li><li class="listitem"> <p class="first-para"><b class="bold">I.</b> Preserve the section entitled "History", and its title, and add to it an item stating at least the title, year, new authors, and publisher of the Modified Version as given on the Title Page. If there is no section entitled "History" in the Document, create one stating the title, year, authors, and publisher of the Document as given on its Title Page, then add an item describing the Modified Version as stated in the previous sentence.</p> </li><li class="listitem"> <p class="first-para"><b class="bold">J.</b> Preserve the network location, if any, given in the Document for public access to a Transparent copy of the Document, and likewise the network locations given in the Document for previous versions it was based on. These may be placed in the "History" section. You may omit a network location for a work that was published at least four years before the Document itself, or if the original publisher of the version it refers to gives permission.</p> </li><li class="listitem"> <p class="first-para"><b class="bold">K.</b> In any section entitled "Acknowledgements" or "Dedications", preserve the section's title, and preserve in the section all the substance and tone of each of the contributor acknowledgements and/or dedications given therein.</p> </li><li class="listitem"> <p class="first-para"><b class="bold">L.</b> 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 <a name="498"></a><a name="IDX-306"></a>the section titles.</p> </li><li class="listitem"> <p class="first-para"><b class="bold">M.</b> Delete any section entitled "Endorsements". Such a section may not be included in the Modified Version.</p> </li><li class="listitem"> <p class="first-para"><b class="bold">N.</b> Do not retitle any existing section as "Endorsements" or to conflict in title with any Invariant Section.</p></li></ul> <p class="para">If the Modified Version includes new front-matter sections or appendices that qualify as Secondary Sections and contain no material copied from the Document, you may at your option designate some or all of these sections as invariant. To do this, add their titles to the list of Invariant Sections in the Modified Version's license notice. These titles must be distinct from any other section titles.</p> <p class="para">You may add a section entitled "Endorsements", provided it contains nothing but endorsements of your Modified Version by various parties--for example, statements of peer review or that the text has been approved by an organization as the authoritative definition of a standard.</p> <p class="para">You may add a passage of up to five words as a Front-Cover Text, and a passage of up to 25 words as a Back-Cover Text, to the end of the list of Cover Texts in the Modified Version. Only one passage of Front-Cover Text and one of Back-Cover Text may be added by (or through arrangements made by) any one entity. If the Document already includes a cover text for the same cover, previously added by you or by arrangement made by the same entity you are acting on behalf of, you may not add another; but you may replace the old one, on explicit permission from the previous publisher that added the old one.</p> <p class="para">The author(s) and publisher(s) of the Document do not by this License give permission to use their names for publicity for or to assert or imply endorsement of any Modified Version.</p> <p class="para"><span class="fixed">5. COMBINING DOCUMENTS</span> </p> <p class="para">You may combine the Document with other documents released under this License, under the terms defined in section 4 above for modified versions, provided that you include in the combination all of the Invariant Sections of all of <a name="499"></a><a name="IDX-307"></a>the original documents, unmodified, and list them all as Invariant Sections of your combined work in its license notice.</p> <p class="para">The combined work need only contain one copy of this License, and multiple identical Invariant Sections may be replaced with a single copy. If there are multiple Invariant Sections with the same name but different contents, make the title of each such section unique by adding at the end of it, in parentheses, the name of the original author or publisher of that section if known, or else a unique number. Make the same adjustment to the section titles in the list of Invariant Sections in the license notice of the combined work.</p> <p class="para">In the combination, you must combine any sections entitled "History" in the various original documents, forming one section entitled "History"; likewise combine any sections entitled "Acknowledgements", and any sections entitled "Dedications". You must delete all sections entitled "Endorsements."</p> <p class="para"><span class="fixed">6. COLLECTIONS OF DOCUMENTS</span> </p> <p class="para">You may make a collection consisting of the Document and other documents released under this License, and replace the individual copies of this License in the various documents with a single copy that is included in the collection, provided that you follow the rules of this License for verbatim copying of each of the documents in all other respects.</p> <p class="para">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.</p> <p class="para"><span class="fixed">7. AGGREGATION WITH INDEPENDENT WORKS</span> </p> <p class="para">A compilation of the Document or its derivatives with other separate and independent documents or works, in or on a volume of a storage or distribution medium, does not as a whole count as a Modified Version of the Document, provided no compilation copyright is claimed for the compilation. Such a compilation is called an "aggregate", and this License does not apply to the other <a name="500"></a><a name="IDX-308"></a>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.</p> <p class="para"><span class="fixed">8. TRANSLATION</span> </p> <p class="para">Translation is considered a kind of modification, so you may distribute translations of the Document under the terms of section 4. Replacing Invariant Sections with translations requires special permission from their copyright holders, but you may include translations of some or all Invariant Sections in addition to the original versions of these Invariant Sections. You may include a translation of this License provided that you also include the original English version of this License. In case of a disagreement between the translation and the original English version of this License, the original English version will prevail.</p> <p class="para"><span class="fixed">9. TERMINATION</span> </p> <p class="para">You may not copy, modify, sublicense, or distribute the Document except as expressly provided for under this License. Any other attempt to copy, modify, sublicense or distribute the Document is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance.</p> <p class="para"><span class="fixed">10. FUTURE REVISIONS OF THIS LICENSE</span> </p> <p class="para">The Free Software Foundation may publish new, revised versions of the GNU Free Documentation License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. See <a class="url" href="http://www.gnu.org/copyleft/" target="_top">http://www.gnu.org/copyleft/</a>.</p> <p class="para">Each version of the License is given a distinguishing version number. If the <a name="501"></a><a name="IDX-309"></a>Document specifies that a particular numbered version of this License "or any later version" applies to it, you have the option of following the terms and conditions either of that specified version or of any later version that has been published (not as a draft) by the Free Software Foundation. If the Document does not specify a version number of this License, you may choose any version ever published (not as a draft) by the Free Software Foundation.</p> <p class="para"><span class="fixed">Addendum</span> </p> <p class="para">To use this License in a document you have written, include a copy of the License in the document and put the following copyright and license notices just after the title page:</p> <blockquote class="blockquote"> <p class="first-para">Copyright © YEAR YOUR NAME.</p> <p class="last-para">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".</p></blockquote> <p class="para">If you have no Invariant Sections, write "with no Invariant Sections" instead of saying which ones are invariant. If you have no Front-Cover Texts, write "no Front-Cover Texts" instead of "Front-Cover Texts being LIST"; likewise for Back-Cover Texts.</p> <p class="para">If your document contains nontrivial examples of program code, we recommend releasing these examples in parallel under your choice of free software license, such as the GNU General Public License, to permit their use in free software.</p><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8901974503278002812-3614831636123756537?l=programminggroundup.blogspot.com'/></div>Adminhttp://www.blogger.com/profile/13783659974416042562noreply@blogger.com0tag:blogger.com,1999:blog-8901974503278002812.post-89465384198893736652007-01-31T19:54:00.000-08:002007-01-31T20:30:32.103-08:00Appendix G: Document History<ul class="itemizedlist"><li class="first-listitem"> <p class="first-para">12/17/2002 - Version 0.5 - Initial posting of book under GNU FDL</p> </li><li class="listitem"> <p class="first-para">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.</p> </li><li class="listitem"> <p class="first-para">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</p> </li><li class="listitem"> <p class="first-para">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.</p> </li><li class="listitem"> <p class="first-para">01/29/2004 - Version 0.9 - Lots of editting of all chapters. Made code more consistent and made explanations clearer. Added some illustrations.</p> </li><li class="listitem"> <p class="first-para">01/31/2004 - Version 1.0 - Rewrote <span class="chapterjump">chapter 9</span>. Added full index. Lots of minor corrections.</p> </li><li class="listitem"> <p class="first-para">04/18/2004 - Version 1.1 - Lots of minor updates based on reader comments. Made cleared distinction between dynamic and shared libraries.</p></li></ul><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8901974503278002812-8946538419889373665?l=programminggroundup.blogspot.com'/></div>Adminhttp://www.blogger.com/profile/13783659974416042562noreply@blogger.com0tag:blogger.com,1999:blog-8901974503278002812.post-32264521480938710972007-01-31T19:51:00.000-08:002007-01-31T20:29:55.015-08:00Appendix F: Using the GDB Debugger<div class="section"> <h2 class="sect2-title"><a name="474"></a>Overview</h2><a name="475"></a><a name="IDX-289"></a> <div class="highlights"> <p class="first-para">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 <i class="emphasis">source debugger.</i> </p> <p class="para">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 <i class="emphasis">source debugger</i> 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.</p> <p class="last-para">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.</p><div class="section"> <h2 class="first-section-title"><a name="476"></a><a name="ap06lev1sec1"></a>An Example Debugging Session</h2> <p class="first-para">The best way to explain how a debugger works is by using it. The program we will be using the debugger on is the <span class="fixed">maximum</span> program used in <span class="chapterjump">Chapter 3</span>. Let's say that you entered the program perfectly, except that you left out the line:</p> <div class="informalexample"><pre class="literallayout"> incl %edi<br /></pre></div> <p class="para">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 <span class="fixed">--gstabs</span> option to the <span class="fixed">as</span> command. So, you would assemble it like this:</p><a name="477"></a><a name="IDX-290"></a> <div class="informalexample"><pre class="literallayout">as --gstabs maximum.s -o maximum.o<br /></pre></div> <p class="para">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 <span class="fixed">gdb ./maximum</span>. Be sure that the source files are in the current directory. The output should look similar to this:</p> <div class="informalexample"><pre class="literallayout">GNU gdb Red Hat Linux (5.2.1-4)<br />Copyright 2002 Free Software Foundation, Inc.<br />GDB is free software, covered by the GNU General Public<br />License, and you are welcome to change it and/or<br />distribute copies of it under certain conditions. Type<br />"show copying" to see the conditions. There is<br />absolutely no warranty for GDB. Type "show warranty"<br />for details.<br />This GDB was configured as "i386-redhat-linux"...<br />(gdb)<br /></pre></div> <p class="para">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 <span class="fixed">run</span>. 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:</p> <div class="informalexample"><pre class="literallayout">Starting program: /home/johnnyb/maximum<br /><br />Program received signal SIGINT, Interrupt.<br />start_loop () at maximum.s:34<br />34 movl data_items(,%edi,4), %eax<br />Current language: auto; currently asm<br />(gdb)<br /></pre></div> <p class="para">This tells you that the program was interrupted by the SIGINT signal (from your control-c), and was within the section labelled <span class="fixed">start_loop</span>, and was executing on line 34 when it stopped. It gives you the code that it is about to execute.</p><a name="478"></a><a name="IDX-291"></a> <p class="para">Depending on exactly when you hit control-c, it may have stopped on a different line or a different instruction than the example.</p> <p class="para">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 <span class="fixed">stepi</span> (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:</p> <div class="informalexample"><pre class="literallayout">(gdb) stepi<br />35 cmpl %ebx, %eax<br />(gdb) stepi<br />36 jle start_loop<br />(gdb) stepi<br />32 cmpl $0, %eax<br />(gdb) stepi<br />33 je loop_exit<br />(gdb) stepi<br />34 movl data_items(,%edi,4), %eax<br />(gdb) stepi<br />35 cmpl %ebx, %eax<br />(gdb) stepi<br />36 jle start_loop<br />(gdb) step<br />32 cmpl $0, %eax<br /></pre></div> <p class="para">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 <i class="emphasis">never stopping.</i> Therefore, to find out what the problem is, let's look at the point in our code where we should be exitting the loop:</p> <div class="informalexample"><pre class="literallayout">cmpl $0, %eax<br />je loop_exit<br /></pre></div> <p class="para">Basically, it is checking to see if <span class="fixed">%eax</span> 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 <a name="479"></a><a name="IDX-292"></a>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 <span class="fixed">loop_exit</span> 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.</p> <p class="para">Neither of those potential problems are the culprit. So, the next option is that perhaps <span class="fixed">%eax</span> has the wrong value. There are two ways to check the contents of register in GDB. The first one is the command <span class="fixed">info register</span>. This will display the contents of all registers in hexadecimal. However, we are only interested in <span class="fixed">%eax</span> at this point. To just display <span class="fixed">%eax</span> we can do <span class="fixed">print/$eax</span> to print it in hexadecimal, or do <span class="fixed">print/d $eax</span> 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:</p> <div class="informalexample"><pre class="literallayout">(gdb) print/d $eax<br />$1 = 3<br />(gdb)<br /></pre></div> <p class="para">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 <span class="fixed">%eax</span> has the number 3. This is not what should be happening. <span class="fixed">%eax</span> should go to the next value in the list in every iteration.</p> <p class="para">Okay, now we know that <span class="fixed">%eax</span> is being loaded with the same value over and over again. Let's search to see where <span class="fixed">%eax</span> is being loaded from. The line of code is this:</p> <div class="informalexample"><pre class="literallayout"> movl data_items(,%edi,4), %eax<br /></pre></div> <p class="para">So, step until this line of code is ready to execute. Now, this code depends on two values <span class="fixed">- data_items</span> and <span class="fixed">%edi. data_items</span> is a symbol, and therefore constant. It's a good idea to check your source code to make sure the label is in <a name="480"></a><a name="IDX-293"></a>front of the right data, but in our case it is. Therefore, we need to look at <span class="fixed">%edi</span>. So, we need to print it out. It will look like this:</p> <div class="informalexample"><pre class="literallayout">(gdb) print/d $edi<br />$2 = 0<br />(gdb)<br /></pre></div> <p class="para">This indicates that <span class="fixed">%edi</span> 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 <span class="fixed">%edi</span>, and how should its value be changed? To answer the first question, we just need to look in the comments. <span class="fixed">%edi</span> is holding the current index of <span class="fixed">data_items</span>. Since our search is a sequential search through the list of numbers in <span class="fixed">data_items</span>, it would make sense that <span class="fixed">%edi</span> should be incremented with every loop iteration.</p> <p class="para">Scanning the code, there is no code which alters <span class="fixed">%edi</span> at all. Therefore, we should add a line to increment <span class="fixed">%edi</span> 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.</p> <p class="last-para">Hopefully this exercise provided some insight into using GDB to help you find errors in your programs.</p><h2 class="first-section-title"><a name="481"></a><a name="ap06lev1sec2"></a>Breakpoints and Other GDB Features</h2> <p class="first-para">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 <i class="emphasis">breakpoints.</i> 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.</p> <p class="para">To set breakpoints you have to set them up before you run the program. Before issuing the <span class="fixed">run</span> command, you can set up breakpoints using the <span class="fixed">break</span> command. <a name="482"></a><a name="IDX-294"></a>For example, to break on line 27, issue the command <span class="fixed">break 27</span>. 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 <span class="fixed">1</span>. This will print out your program with line numbers a screen at a time.</p> <p class="para">When dealing with functions, you can also break on the function names. For example, in the factorial program in <span class="chapterjump">Chapter 4</span>, we could set a breakpoint for the factorial function by typing in <span class="fixed">break factorial</span>. This will cause the debugger to break immediately after the function call and the function setup (it skips the pushing of <span class="fixed">%ebp</span> and the copying of <span class="fixed">%esp</span>).</p> <p class="para">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 <span class="fixed">nexti</span> command instead of the <span class="fixed">stepi</span> command, GDB will wait until completion of the function before going on. Otherwise, with <span class="fixed">stepi</span>, GDB would step you through every instruction within every called function.</p> <table class="warning" border="0" cellpadding="0" cellspacing="0"> <tbody> <tr> <td class="admon-check" valign="top"><br /></td> <td class="admon-title" valign="top">Warning </td> <td class="admon-body" valign="top"> <p class="first-para">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.</p></td></tr></tbody></table><br /><div class="appendix"><a name="ap06"></a> <div class="section"> <h2 class="first-section-title"><a name="483"></a><a name="ap06lev1sec3"></a>GDB Quick-Reference</h2> <p class="first-para">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.</p><a name="484"></a><a name="IDX-295"></a> <div class="table"><a name="485"></a><a name="ap06table01"></a><span class="table-title"><span class="table-titlelabel">Table F-1: </span>Common GDB Debugging Commands</span> <table border="1"> <thead> <tr valign="top"> <th class="th" scope="col" colspan="2" align="left" valign="top"> <p class="table-para"><b class="bold">Miscellaneous</b> </p></th></tr></thead> <tbody> <tr valign="top"> <td class="td" align="left"> <p class="table-para">quit</p></td> <td class="td" align="left"> <p class="table-para">Exit GDB</p></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">help [cmd]</p></td> <td class="td" align="left"> <p class="table-para">Print description of debugger command <span class="fixed">cmd</span>. Without <span class="fixed">cmd</span>, prints a list of topics.</p></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">directory [dir1] [dir2] ...</p></td> <td class="td" align="left"> <p class="table-para">Add directories <span class="fixed">dir1</span>, <span class="fixed">dir2</span>, etc. to the list of directories searched for source files.</p></td></tr></tbody></table> <table border="1"> <thead> <tr valign="top"> <th class="th" scope="col" colspan="2" align="left" valign="top"> <p class="table-para"><b class="bold">Running the Program</b> </p></th></tr></thead> <tbody> <tr valign="top"> <td class="td" align="left"> <p class="table-para">run [arg1] [arg2] ...</p></td> <td class="td" align="left"> <p class="table-para">Run the program with command line arguments <span class="fixed">arg1</span>, <span class="fixed">arg2</span>, etc.</p></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">set args arg1 [arg2] ...</p></td> <td class="td" align="left"> <p class="table-para">Set the program's command-line arguments to <span class="fixed">arg1</span>, <span class="fixed">arg2</span>, etc.</p></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">show args</p></td> <td class="td" align="left"> <p class="table-para">Print the program's command-line arguments.</p></td></tr></tbody></table> <table border="1"> <thead> <tr valign="top"> <th class="th" scope="col" colspan="2" align="left" valign="top"> <p class="table-para"><b class="bold">Using Breakpoints</b> </p></th></tr></thead> <tbody> <tr valign="top"> <td class="td" align="left"> <p class="table-para">info breakpoints</p></td> <td class="td" align="left"> <p class="table-para">Print a list of all breakpoints and their numbers (breakpoint numbers are used for other breakpoint commands).</p></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">break <i class="emphasis">linenum</i> </p></td> <td class="td" align="left"> <p class="table-para">Set a breakpoint at line number <i class="emphasis">linenum.</i> </p></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">break <i class="emphasis">*addr</i> </p></td> <td class="td" align="left"> <p class="table-para">Set a breakpoint at memory address <i class="emphasis">addr.</i> </p></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">break <i class="emphasis">fn</i> </p></td> <td class="td" align="left"> <p class="table-para">Set a breakpoint at the beginning of function <i class="emphasis">fn.</i> </p></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">condition <i class="emphasis">bpnum expr</i> </p></td> <td class="td" align="left"> <p class="table-para">Break at breakpoint <i class="emphasis">bpnum</i> only if expression <i class="emphasis">expr</i> is non-zero.</p><a name="486"></a><a name="IDX-296"></a></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">command [<i class="emphasis">bpnum</i>] <i class="emphasis">cmd1</i> [<i class="emphasis">cmd2</i>] ...</p></td> <td class="td" align="left"> <p class="table-para">Execute commands <i class="emphasis">cmd1, cmd2,</i> etc. whenever breakpoint <i class="emphasis">bpnum</i> (or the current breakpoint) is hit.</p></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">Continue</p></td> <td class="td" align="left"> <p class="table-para">Continue executing the program.</p></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">Kill</p></td> <td class="td" align="left"> <p class="table-para">Stop executing the program.</p></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">delete [<i class="emphasis">bpnum1</i>] [<i class="emphasis">bpnum2</i>] ...</p></td> <td class="td" align="left"> <p class="table-para">Delete breakpoints <i class="emphasis">bpnuml, bpnum2,</i> etc., or all breakpoints if none specified.</p></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">clear <i class="emphasis">*addr</i> </p></td> <td class="td" align="left"> <p class="table-para">Clear the breakpoint at memory address <i class="emphasis">addr.</i> </p></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">clear [<i class="emphasis">fn</i>]</p></td> <td class="td" align="left"> <p class="table-para">Clear the breakpoint at function <i class="emphasis">fn</i>, or the current breakpoint.</p></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">clear <i class="emphasis">linenum</i> </p></td> <td class="td" align="left"> <p class="table-para">Clear the breakpoint at line number <i class="emphasis">linenum.</i> </p></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">disable [<i class="emphasis">bpnum1</i>] [<i class="emphasis">bpnum2</i>] ...</p></td> <td class="td" align="left"> <p class="table-para">Disable breakpoints <i class="emphasis">bpnum1, bpnum2,</i> etc., or all breakpoints if none specified.</p></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">enable [<i class="emphasis">bpnum1</i>] [<i class="emphasis">bpnum2</i>] ...</p></td> <td class="td" align="left"> <p class="table-para">Enable breakpoints <i class="emphasis">bpnum1, bpnum2,</i> etc., or all breakpoints if none specified.</p></td></tr></tbody></table> <table border="1"> <thead> <tr valign="top"> <th class="th" scope="col" colspan="2" align="left" valign="top"> <p class="table-para"><b class="bold">Stepping through the Program</b> </p></th></tr></thead> <tbody> <tr valign="top"> <td class="td" align="left"> <p class="table-para">nexti</p></td> <td class="td" align="left"> <p class="table-para">"Step over" the next instruction (doesn't follow function calls).</p></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">stepi</p></td> <td class="td" align="left"> <p class="table-para">"Step into" the next instruction (follows function calls).</p></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">finish</p></td> <td class="td" align="left"> <p class="table-para">"Step out" of the current function.</p></td></tr></tbody></table> <table border="1"> <thead> <tr valign="top"> <th class="th" scope="col" colspan="2" align="left" valign="top"> <p class="table-para"><b class="bold">Examining Registers and Memory</b> </p></th></tr></thead> <tbody> <tr valign="top"> <td class="td" align="left"> <p class="table-para">info registers</p></td> <td class="td" align="left"> <p class="table-para">Print the contents of all registers.</p><a name="487"></a><a name="IDX-297"></a></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">print/<i class="emphasis">f $reg</i> </p></td> <td class="td" align="left"> <p class="table-para">Print the contents of register <i class="emphasis">reg</i> using format <i class="emphasis">f</i>. The format can be x (hexadecimal), u (unsigned decimal), o (octal), a(address), c (character), or f (floating point).</p></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">x/<i class="emphasis">rsf addr</i> </p></td> <td class="td" align="left"> <p class="table-para">Print the contents of memory address <i class="emphasis">addr</i> using repeat count <i class="emphasis">r</i>, size <i class="emphasis">s,</i> and format <i class="emphasis">f</i>. 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).</p></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">info display</p></td> <td class="td" align="left"> <p class="table-para">Shows a numbered list of expressions set up to display automatically at each break.</p></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">display/<i class="emphasis">f $reg</i> </p></td> <td class="td" align="left"> <p class="table-para">At each break, print the contents of register <i class="emphasis">reg</i> using format <i class="emphasis">f</i>.</p></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">display/<i class="emphasis">s</i>i addr</p></td> <td class="td" align="left"> <p class="table-para">At each break, print the contents of memory address <i class="emphasis">addr</i> using size <i class="emphasis">s</i> (same options as for the x command).</p></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">display/<i class="emphasis">ss</i> addr</p></td> <td class="td" align="left"> <p class="table-para">At each break, print the string of size <i class="emphasis">s</i> that begins in memory address <i class="emphasis">addr.</i> </p></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">undisplay <i class="emphasis">displaynum</i> </p></td> <td class="td" align="left"> <p class="table-para">Remove <i class="emphasis">displaynum</i> from the display list.</p></td></tr></tbody></table> <table border="1"> <thead> <tr valign="top"> <th class="th" scope="col" colspan="2" align="left" valign="top"> <p class="table-para"><b class="bold">Examining the Call Stack</b> </p></th></tr></thead> <tbody> <tr valign="top"> <td class="td" align="left"> <p class="table-para">where</p></td> <td class="td" align="left"> <p class="table-para">Print the call stack.</p></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">backtrace</p></td> <td class="td" align="left"> <p class="table-para">Print the call stack.</p><a name="488"></a><a name="IDX-298"></a></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">frame</p></td> <td class="td" align="left"> <p class="table-para">Print the top of the call stack.</p></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">up</p></td> <td class="td" align="left"> <p class="table-para">Move the context toward the bottom of the call stack.</p></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">down</p></td> <td class="td" align="left"> <p class="table-para">Move the context toward the top of the call stack.</p></td></tr></tbody></table></div></div></div><br /><br /></div></div></div><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8901974503278002812-3226452148093871097?l=programminggroundup.blogspot.com'/></div>Adminhttp://www.blogger.com/profile/13783659974416042562noreply@blogger.com0tag:blogger.com,1999:blog-8901974503278002812.post-22756364825067325902007-01-31T19:48:00.000-08:002007-01-31T19:51:18.702-08:00Appendix E: C Idioms in Assembly Language<div class="highlights"> <p class="first-para">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.</p></div> <div class="section"> <h2 class="sect2-title"><a name="455"></a><a name="ap05lev1sec1"></a>If Statement</h2> <p class="first-para">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:</p> <div class="informalexample"><pre class="literallayout">if (a == b)<br />{<br />/* True Branch Code Here */<br />}<br />else<br />{<br />/* False Branch Code Here */<br />}<br /><br />/* At This Point, Reconverge */<br /></pre></div> <p class="para">In assembly language, this can be rendered as:</p> <div class="informalexample"><pre class="literallayout"> #Move a and b into registers for comparison<br />movl a, %eax<br />movl b, %ebx<br /><br />#Compare<br />cmpl %eax, %ebx<br /><br />#If True, go to true branch<br />je true_branch<a name="456"></a><a name="IDX-278"></a><br />false_branch: #This label is unnecessary,<br /> #only here for documentation<br />#False Branch Code Here<br /><br />#Jump to recovergence point<br />jmp reconverge<br /><br /><br />true_branch:<br />#True Branch Code Here<br /><br /><br />reconverge:<br />#Both branches recoverge to this point<br /></pre></div> <p class="para">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.</p> <p class="last-para">A case statement is written just like a sequence of if statements.</p><div class="section"> <h2 class="first-section-title"><a name="457"></a><a name="ap05lev1sec2"></a>Function Call</h2> <p class="first-para">A function call in assembly language simply requires pushing the arguments to the function onto the stack in <i class="emphasis">reverse</i> order, and issuing a <span class="fixed">call</span> instruction. After calling, the arguments are then popped back off of the stack. For example, consider the C code:</p> <div class="informalexample"><pre class="literallayout"> printf("The number is %d", 88);<br /></pre></div> <p class="para">In assembly language, this would be rendered as:</p> <div class="informalexample"><pre class="literallayout"> .section .data<br />text_string:<br />.ascii "The number is %d\0"<a name="458"></a><a name="IDX-279"></a><br />.section .text<br />pushl $88<br />pushl $text_string<br />call printf<br />popl %eax<br />popl %eax #%eax is just a dummy variable,<br /> #nothing is actually being done<br /> #with the value. You can also<br /> #directly re-adjust %esp to the<br /> #proper location.<br /><br /></pre><div class="appendix"><a name="ap05"></a> <div class="section"> <h2 class="first-section-title"><a name="459"></a><a name="ap05lev1sec3"></a>Variables and Assignment</h2> <p class="first-para">Global and static variables are declared using <span class="fixed">.data</span> or <span class="fixed">.bss</span> 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.</p> <p class="para">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:</p> <div class="informalexample"><pre class="literallayout">int my_global_var;<br /><br />int foo()<br />{<br />int my_local_var;<br /><br />my_local_var = 1;<br />my_global_var = 2;<br /><br />return 0;<br />}<br /><a name="460"></a><a name="IDX-280"></a><br /></pre></div> <p class="para">This would be rendered in assembly language as:</p> <div class="informalexample"><pre class="literallayout"> .section .data<br />.lcomm my_global_var, 4<br /><br />.type foo, @function<br />foo:<br />pushl %ebp #Save old base pointer<br />movl %esp, $ebp #make stack pointer base pointer<br />subl $4, %esp #Make room for my_local_var<br />.equ my_local_var, -4 #Can now use my_local_var to<br /> #find the local variable<br /><br /><br />movl $1, my_local_var(%ebp)<br />movl $2, my_global_var<br /><br />movl %ebp, %esp #Clean up function and return<br />popl %ebp<br />ret<br /></pre></div> <p class="para">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.</p> <p class="last-para">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 <span class="fixed">foo</span>, 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 <span class="fixed">volatile</span> to make sure all modifications and references to the variable are done to the memory <a name="461"></a><a name="IDX-281"></a>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.</p><div class="section"> <h2 class="first-section-title"><a name="462"></a><a name="ap05lev1sec4"></a>Loops</h2> <p class="first-para">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.</p> <p class="para">In C, a while loop looks like this:</p> <div class="informalexample"><pre class="literallayout">while(a < b)<br />{<br />/* Do stuff here */<br />}<br /><br />/* Finished Looping */<br /></pre></div> <p class="para">This can be rendered in assembly language like this:</p> <div class="informalexample"><pre class="literallayout">loop_begin:<br />movl a, %eax<br />movl b, %ebx<br />cmpl %eax, %ebx<br />jge loop_end<br /><br />loop_body:<br />#Do stuff here<br /><br />jmp loop_begin<br /><br />loop_end:<br />#Finished looping<br /><a name="463"></a><a name="IDX-282"></a><br /></pre></div> <p class="para">The x86 assembly language has some direct support for looping as well. The <span class="fixed">%ecx</span> register can be used as a counter that <i class="emphasis">ends</i> with zero. The <span class="fixed">loop</span> instruction will decrement <span class="fixed">%ecx</span> and jump to a specified address unless <span class="fixed">%ecx</span> is zero. For example, if you wanted to execute a statement 100 times, you would do this in C:</p> <div class="informalexample"><pre class="literallayout"> for(i=0; i < 100; i++)<br />{<br /> /* Do process here */<br />}<br /></pre></div> <p class="para">In assembly language it would be written like this:</p> <div class="informalexample"><pre class="literallayout">loop_initialize:<br />movl $100, %ecx<br />loop_begin:<br />#<br />#Do Process Here<br />#<br /><br />#Decrement %ecx and loops if not zero<br />loop loop_begin<br /><br />rest_of_program:<br />#Continues on to here<br /></pre></div> <p class="para">One thing to notice is that the <span class="fixed">loop</span> instruction <i class="emphasis">requires you to be counting backwards to zero.</i> If you need to count forwards or use another ending number, you should use the loop form which does not include the <span class="fixed">loop</span> instruction.</p> <p class="last-para">For really tight loops of character string operations, there is also the <span class="fixed">rep</span> instruction, but we will leave learning about that as an exercise to the reader.</p></div></div></div><br /><div class="section"> <h2 class="first-section-title"><a name="464"></a><a name="ap05lev1sec5"></a>Structs</h2> <p class="first-para">Structs are simply descriptions of memory blocks. For example, in C you can say:</p><a name="465"></a><a name="IDX-283"></a> <div class="informalexample"><pre class="literallayout">struct person {<br />char firstname[40];<br />char lastname[40];<br />int age;<br />};<br /></pre></div> <p class="para">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 <span class="fixed">.equ</span> directives in assembly language. Like this:</p> <div class="informalexample"><pre class="literallayout"> .equ PERSON_SIZE, 84<br />.equ PERSON_FIRSTNAME_OFFSET, 0<br />.equ PERSON_LASTNAME_OFFSET, 40<br />.equ PERSON_AGE_OFFSET, 80<br /></pre></div> <p class="para">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:</p> <div class="informalexample"><pre class="literallayout">void foo()<br />{<br />struct person p;<br /><br />/* Do stuff here */<br />}<br /></pre></div> <p class="para">In assembly language you would have:</p> <div class="informalexample"><pre class="literallayout">foo:<br />#Standard header beginning<br />pushl %ebp<br />movl %esp, %ebp<br /><br />#Reserve our local variable<br />subl $PERSON_SIZE, %esp<br />#This is the variable's offset from %ebp<a name="466"></a><a name="IDX-284"></a><br />.equ P_VAR, 0 - PERSON_SIZE<br /><br />#Do Stuff Here<br /><br />#Standard function ending<br />movl %ebp, %esp<br />popl %ebp<br />ret<br /></pre></div> <p class="para">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:</p> <div class="informalexample"><pre class="literallayout"> p.age = 30;<br /></pre></div> <p class="para">In assembly language it would look like this:</p> <div class="informalexample"><pre class="literallayout"> movl $30, P_VAR + PERSON_AGE_OFFSET(%ebp)<br /><br /></pre><h2 class="first-section-title"><a name="467"></a><a name="ap05lev1sec6"></a>Pointers</h2> <p class="first-para">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:</p> <div class="informalexample"><pre class="literallayout">int global_data = 30;<br /></pre></div> <p class="para">In assembly language, this would be:</p> <div class="informalexample"><pre class="literallayout"> .section .data<br />global_data:<br />.long 30<br /></pre></div> <p class="para">Taking the address of this data in C:</p> <div class="informalexample"><pre class="literallayout"> a = &global_data;<br /><a name="468"></a><a name="IDX-285"></a><br /></pre></div> <p class="para">Taking the address of this data in assembly language:</p> <div class="informalexample"><pre class="literallayout"> movl $global_data, %eax<br /></pre></div> <p class="para">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.</p> <p class="para">Local variables are a little more difficult, but not much. Here is how you take the address of a local variable in C:</p> <div class="informalexample"><pre class="literallayout">void foo()<br />{<br />int a;<br />int *b;<br /><br />a = 30;<br /><br />b = &a;<br /><br />*b = 44;<br />}<br /></pre></div> <p class="para">The same code in assembly language:</p> <div class="informalexample"><pre class="literallayout">foo:<br />#Standard opening<br />pushl %ebp<br />movl %esp, %ebp<br /><br />#Reserve two words of memory<br />subl $8, $esp<br />.equ A_VAR, -4<br />.equ B_VAR, -8<br /><br />#a = 30<a name="469"></a><a name="IDX-286"></a><br />movl $30, A_VAR(%ebp)<br /><br />#b = &a<br />movl $A_VAR, B_VAR(%ebp)<br />addl %ebp, B_VAR(%ebp)<br /><br />#*b = 30<br />movl B_VAR(%ebp), %eax<br />movl $30, (%eax)<br /><br />#Standard closing<br />movl %ebp, %esp<br />popl %ebp<br />ret<br /></pre></div> <p class="para">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 <span class="fixed">leal</span>, 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:</p> <div class="informalexample"><pre class="literallayout"> #b = &a<br />leal A_VAR(%ebp), %eax<br />movl %eax, B_VAR(%ebp)<br /></pre></div> <p class="last-para">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.</p><div class="appendix"><a name="ap05"></a> <div class="section"> <h2 class="first-section-title"><a name="470"></a><a name="ap05lev1sec7"></a>Getting GCC to Help</h2> <p class="first-para">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:</p><a name="471"></a><a name="IDX-287"></a> <div class="informalexample"><pre class="literallayout">gcc -S file.c<br /></pre></div> <p class="para">The output will be in <span class="fixed">file.s.</span> 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 <span class="fixed">-O0</span> so that the assembly language output will follow your source code better.</p> <p class="para">Something else you might notice is that GCC reserves more stack space for local variables than we do, and then AND's %<span class="fixed">esp</span> <sup>[<a href="#ftn.N40" name="N40">1</a>]</sup> This is to increase memory and cache efficiency by double-word aligning variables.</p> <p class="para">Finally, at the end of functions, we usually do the following instructions to clean up the stack before issuing a <span class="fixed">ret</span> instruction:</p> <div class="informalexample"><pre class="literallayout"> movl %ebp, %esp<br />popl %ebp<br /></pre></div> <p class="para">However, GCC output will usually just include the instruction <span class="fixed">leave.</span> This instruction is simply the combination of the above two instructions. We do not use <span class="fixed">leave</span> in this text because we want to be clear about exactly what is happening at the processor level.</p> <p class="para">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.</p><a name="472"></a><a name="IDX-288"></a></div> <div class="footnotes"> <div class="footnote"> <p><sup>[<a href="#N40" name="ftn.N40">1</a>]</sup>Note that different versions of GCC do this differently.</p></div></div></div><pre class="literallayout"><br /><br /></pre></div></div><pre class="literallayout"><br /></pre></div></div></div><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8901974503278002812-2275636482506732590?l=programminggroundup.blogspot.com'/></div>Adminhttp://www.blogger.com/profile/13783659974416042562noreply@blogger.com0tag:blogger.com,1999:blog-8901974503278002812.post-35884461403494075702007-01-31T19:47:00.000-08:002007-01-31T19:48:03.282-08:00Appendix D: Table of ASCII Codes<p class="para">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.</p><a name="451"></a><a name="ap04table01"></a> <table class="table" border="1"> <caption class="table-title"><span class="table-title"><span class="table-titlelabel">Table D-1: </span>Table of ASCII codes in decimal</span> </caption> <thead> <tr valign="top"> <th class="th" scope="col" align="left"> </th> <th class="th" scope="col" align="left"> <p class="table-para">+0</p></th> <th class="th" scope="col" align="left"> <p class="table-para">+1</p></th> <th class="th" scope="col" align="left"> <p class="table-para">+2</p></th> <th class="th" scope="col" align="left"> <p class="table-para">+3</p></th> <th class="th" scope="col" align="left"> <p class="table-para">+4</p></th> <th class="th" scope="col" align="left"> <p class="table-para">+5</p></th> <th class="th" scope="col" align="left"> <p class="table-para">+6</p></th> <th class="th" scope="col" align="left"> <p class="table-para">+7</p></th></tr></thead> <tbody> <tr valign="top"> <td class="td" align="left"> <p class="table-para">0</p></td> <td class="td" align="left"> <p class="table-para">NUL</p></td> <td class="td" align="left"> <p class="table-para">SOH</p></td> <td class="td" align="left"> <p class="table-para">STX</p></td> <td class="td" align="left"> <p class="table-para">ETX</p></td> <td class="td" align="left"> <p class="table-para">EOT</p></td> <td class="td" align="left"> <p class="table-para">ENQ</p></td> <td class="td" align="left"> <p class="table-para">ACK</p></td> <td class="td" align="left"> <p class="table-para">BEL</p></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">8</p></td> <td class="td" align="left"> <p class="table-para">BS</p></td> <td class="td" align="left"> <p class="table-para">HT</p></td> <td class="td" align="left"> <p class="table-para">LF</p></td> <td class="td" align="left"> <p class="table-para">VT</p></td> <td class="td" align="left"> <p class="table-para">FF</p></td> <td class="td" align="left"> <p class="table-para">CR</p></td> <td class="td" align="left"> <p class="table-para">SO</p></td> <td class="td" align="left"> <p class="table-para">SI</p></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">16</p></td> <td class="td" align="left"> <p class="table-para">DLE</p></td> <td class="td" align="left"> <p class="table-para">DC1</p></td> <td class="td" align="left"> <p class="table-para">DC2</p></td> <td class="td" align="left"> <p class="table-para">DC3</p></td> <td class="td" align="left"> <p class="table-para">DC4</p></td> <td class="td" align="left"> <p class="table-para">NAK</p></td> <td class="td" align="left"> <p class="table-para">SYN</p></td> <td class="td" align="left"> <p class="table-para">ETB</p></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">24</p></td> <td class="td" align="left"> <p class="table-para">CAN</p></td> <td class="td" align="left"> <p class="table-para">EM</p></td> <td class="td" align="left"> <p class="table-para">SUB</p></td> <td class="td" align="left"> <p class="table-para">ESC</p></td> <td class="td" align="left"> <p class="table-para">FS</p></td> <td class="td" align="left"> <p class="table-para">GS</p></td> <td class="td" align="left"> <p class="table-para">RS</p></td> <td class="td" align="left"> <p class="table-para">US</p></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">32</p></td> <td class="td" align="left"> </td> <td class="td" align="left"> <p class="table-para">!</p></td> <td class="td" align="left"> <p class="table-para">"</p></td> <td class="td" align="left"> <p class="table-para">#</p></td> <td class="td" align="left"> <p class="table-para">$</p></td> <td class="td" align="left"> <p class="table-para">%</p></td> <td class="td" align="left"> <p class="table-para">&</p></td> <td class="td" align="left"> <p class="table-para">'</p></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">40</p></td> <td class="td" align="left"> <p class="table-para">(</p></td> <td class="td" align="left"> <p class="table-para">)</p></td> <td class="td" align="left"> <p class="table-para">*</p></td> <td class="td" align="left"> <p class="table-para">+</p></td> <td class="td" align="left"> <p class="table-para">,</p></td> <td class="td" align="left"> <p class="table-para">-</p></td> <td class="td" align="left"> <p class="table-para">.</p></td> <td class="td" align="left"> <p class="table-para">/</p></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">48</p></td> <td class="td" align="left"> <p class="table-para">0</p></td> <td class="td" align="left"> <p class="table-para">1</p></td> <td class="td" align="left"> <p class="table-para">2</p></td> <td class="td" align="left"> <p class="table-para">3</p></td> <td class="td" align="left"> <p class="table-para">4</p></td> <td class="td" align="left"> <p class="table-para">5</p></td> <td class="td" align="left"> <p class="table-para">6</p></td> <td class="td" align="left"> <p class="table-para">7</p></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">56</p></td> <td class="td" align="left"> <p class="table-para">8</p></td> <td class="td" align="left"> <p class="table-para">9</p></td> <td class="td" align="left"> <p class="table-para">:</p></td> <td class="td" align="left"> <p class="table-para">;</p></td> <td class="td" align="left"> <p class="table-para"><</p></td> <td class="td" align="left"> <p class="table-para">=</p></td> <td class="td" align="left"> <p class="table-para">></p></td> <td class="td" align="left"> <p class="table-para">?</p></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">64</p></td> <td class="td" align="left"> <p class="table-para">@</p></td> <td class="td" align="left"> <p class="table-para">A</p></td> <td class="td" align="left"> <p class="table-para">B</p></td> <td class="td" align="left"> <p class="table-para">C</p></td> <td class="td" align="left"> <p class="table-para">D</p></td> <td class="td" align="left"> <p class="table-para">E</p></td> <td class="td" align="left"> <p class="table-para">F</p></td> <td class="td" align="left"> <p class="table-para">G</p></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">72</p></td> <td class="td" align="left"> <p class="table-para">H</p></td> <td class="td" align="left"> <p class="table-para">I</p></td> <td class="td" align="left"> <p class="table-para">J</p></td> <td class="td" align="left"> <p class="table-para">K</p></td> <td class="td" align="left"> <p class="table-para">L</p></td> <td class="td" align="left"> <p class="table-para">M</p></td> <td class="td" align="left"> <p class="table-para">N</p></td> <td class="td" align="left"> <p class="table-para">O</p></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">80</p></td> <td class="td" align="left"> <p class="table-para">P</p></td> <td class="td" align="left"> <p class="table-para">Q</p></td> <td class="td" align="left"> <p class="table-para">R</p></td> <td class="td" align="left"> <p class="table-para">S</p></td> <td class="td" align="left"> <p class="table-para">T</p></td> <td class="td" align="left"> <p class="table-para">U</p></td> <td class="td" align="left"> <p class="table-para">V</p></td> <td class="td" align="left"> <p class="table-para">W</p></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">88</p></td> <td class="td" align="left"> <p class="table-para">X</p></td> <td class="td" align="left"> <p class="table-para">Y</p></td> <td class="td" align="left"> <p class="table-para">Z</p></td> <td class="td" align="left"> <p class="table-para">[</p></td> <td class="td" align="left"> <p class="table-para">\</p></td> <td class="td" align="left"> <p class="table-para">]</p></td> <td class="td" align="left"> <p class="table-para">^</p></td> <td class="td" align="left"> <p class="table-para">_</p></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">96</p></td> <td class="td" align="left"> <p class="table-para">'</p></td> <td class="td" align="left"> <p class="table-para">a</p></td> <td class="td" align="left"> <p class="table-para">b</p></td> <td class="td" align="left"> <p class="table-para">c</p></td> <td class="td" align="left"> <p class="table-para">d</p></td> <td class="td" align="left"> <p class="table-para">e</p></td> <td class="td" align="left"> <p class="table-para">f</p></td> <td class="td" align="left"> <p class="table-para">g</p></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">104</p></td> <td class="td" align="left"> <p class="table-para">h</p></td> <td class="td" align="left"> <p class="table-para">i</p></td> <td class="td" align="left"> <p class="table-para">j</p></td> <td class="td" align="left"> <p class="table-para">k</p></td> <td class="td" align="left"> <p class="table-para">l</p></td> <td class="td" align="left"> <p class="table-para">m</p></td> <td class="td" align="left"> <p class="table-para">n</p></td> <td class="td" align="left"> <p class="table-para">o</p></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">112</p></td> <td class="td" align="left"> <p class="table-para">p</p></td> <td class="td" align="left"> <p class="table-para">q</p></td> <td class="td" align="left"> <p class="table-para">r</p></td> <td class="td" align="left"> <p class="table-para">s</p></td> <td class="td" align="left"> <p class="table-para">t</p></td> <td class="td" align="left"> <p class="table-para">u</p></td> <td class="td" align="left"> <p class="table-para">v</p></td> <td class="td" align="left"> <p class="table-para">w</p></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">120</p></td> <td class="td" align="left"> <p class="table-para">x</p></td> <td class="td" align="left"> <p class="table-para">y</p></td> <td class="td" align="left"> <p class="table-para">z</p></td> <td class="td" align="left"> <p class="table-para">{</p></td> <td class="td" align="left"> <p class="table-para">|</p></td> <td class="td" align="left"> <p class="table-para">}</p></td> <td class="td" align="left"> <p class="table-para">~</p></td> <td class="td" align="left"> <p class="table-para">DEL</p></td></tr></tbody></table> <p class="para">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 <a name="452"></a><a name="IDX-276"></a>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.</p> <p class="last-para">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 <a class="url" href="http://www.joelonsoftware.com/articles/Unicode.html" target="_top">http://www.joelonsoftware.com/articles/Unicode.html</a> </p><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8901974503278002812-3588446140349407570?l=programminggroundup.blogspot.com'/></div>Adminhttp://www.blogger.com/profile/13783659974416042562noreply@blogger.com0tag:blogger.com,1999:blog-8901974503278002812.post-36561643374440268632007-01-31T19:45:00.000-08:002007-01-31T19:46:54.937-08:00Appendix C: Important System Calls<p class="para">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 <a class="url" href="http://www.gnu.org/software/libc/manual/" target="_top">http://www.gnu.org/software/libc/manual/</a> </p> <p class="para">Remember that <span class="fixed">%eax</span> holds the system call numbers, and that the return values and error codes are also stored in <span class="fixed">%eax</span>.</p><a name="445"></a><a name="ap03table01"></a> <table class="table" border="1"> <caption class="table-title"><span class="table-title"><span class="table-titlelabel">Table C-1: </span>Important Linux System Calls</span> </caption> <thead> <tr valign="top"> <th class="th" scope="col" align="left"> <p class="table-para"><b class="bold"><span class="fixed">%eax</span></b> </p></th> <th class="th" scope="col" align="left"> <p class="table-para"><b class="bold">Name</b> </p></th> <th class="th" scope="col" align="left"> <p class="table-para"><b class="bold"><span class="fixed">%ebx</span></b> </p></th> <th class="th" scope="col" align="left"> <p class="table-para"><b class="bold"><span class="fixed">%ecx</span></b> </p></th> <th class="th" scope="col" align="left"> <p class="table-para"><b class="bold"><span class="fixed">%edx</span></b> </p></th> <th class="th" scope="col" align="left"> <p class="table-para"><b class="bold">Notes</b> </p></th></tr></thead> <tbody> <tr valign="top"> <td class="td" align="left"> <p class="table-para">1</p></td> <td class="td" align="left"> <p class="table-para">exit</p></td> <td class="td" align="left"> <p class="table-para">return value (int)</p></td> <td class="td" align="left"> </td> <td class="td" align="left"> </td> <td class="td" align="left"> <p class="table-para">Exits the program</p></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">3</p></td> <td class="td" align="left"> <p class="table-para">read</p></td> <td class="td" align="left"> <p class="table-para">file descriptor</p></td> <td class="td" align="left"> <p class="table-para">buffer start</p></td> <td class="td" align="left"> <p class="table-para">buffer size (int)</p></td> <td class="td" align="left"> <p class="table-para">Reads into the given buffer</p></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">4</p></td> <td class="td" align="left"> <p class="table-para">write</p></td> <td class="td" align="left"> <p class="table-para">file descriptor</p></td> <td class="td" align="left"> <p class="table-para">buffer start</p></td> <td class="td" align="left"> <p class="table-para">buffer size (int)</p></td> <td class="td" align="left"> <p class="table-para">Writes the buffer to the file descriptor</p></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">5</p></td> <td class="td" align="left"> <p class="table-para">open</p></td> <td class="td" align="left"> <p class="table-para">null-terminate file name</p></td> <td class="td" align="left"> <p class="table-para">option list</p></td> <td class="td" align="left"> <p class="table-para">permission mode</p></td> <td class="td" align="left"> <p class="table-para">Opens the given file. Returns the file descriptor or an error number.</p></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">6</p></td> <td class="td" align="left"> <p class="table-para">close</p></td> <td class="td" align="left"> <p class="table-para">file descriptor</p></td> <td class="td" align="left"> </td> <td class="td" align="left"> </td> <td class="td" align="left"> <p class="table-para">Closes the give file descriptor</p><a name="446"></a><a name="IDX-272"></a></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">12</p></td> <td class="td" align="left"> <p class="table-para">chdir</p></td> <td class="td" align="left"> <p class="table-para">null-terminated directory name</p></td> <td class="td" align="left"> </td> <td class="td" align="left"> </td> <td class="td" align="left"> <p class="table-para">Changes the current directory of your program.</p></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">19</p></td> <td class="td" align="left"> <p class="table-para">lseek</p></td> <td class="td" align="left"> <p class="table-para">file descriptor</p></td> <td class="td" align="left"> <p class="table-para">offset</p></td> <td class="td" align="left"> <p class="table-para">mode</p></td> <td class="td" align="left"> <p class="table-para">Repositions where you are in the given file. The mode (called the "whence") should be 0 for absolute positioning, and 1 for relative positioning.</p></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">20</p></td> <td class="td" align="left"> <p class="table-para">getpid</p></td> <td class="td" align="left"> </td> <td class="td" align="left"> </td> <td class="td" align="left"> </td> <td class="td" align="left"> <p class="table-para">Returns the process ID of the current process.</p></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">39</p></td> <td class="td" align="left"> <p class="table-para">mkdir</p></td> <td class="td" align="left"> <p class="table-para">null-terminated directory name</p></td> <td class="td" align="left"> <p class="table-para">permission mode</p></td> <td class="td" align="left"> </td> <td class="td" align="left"> <p class="table-para">Creates the given directory. Assumes all directories leading up to it already exist.</p></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">40</p></td> <td class="td" align="left"> <p class="table-para">rmdir</p></td> <td class="td" align="left"> <p class="table-para">null-terminated directory name</p></td> <td class="td" align="left"> </td> <td class="td" align="left"> </td> <td class="td" align="left"> <p class="table-para">Removes the given directory.</p></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">41</p></td> <td class="td" align="left"> <p class="table-para">dup</p></td> <td class="td" align="left"> <p class="table-para">file descriptor</p></td> <td class="td" align="left"> </td> <td class="td" align="left"> </td> <td class="td" align="left"> <p class="table-para">Returns a new file descriptor pat works just like the existing file descriptor.</p></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">42</p></td> <td class="td" align="left"> <p class="table-para">pipe</p></td> <td class="td" align="left"> <p class="table-para">pipe array</p></td> <td class="td" align="left"> </td> <td class="td" align="left"> </td> <td class="td" align="left"> <p class="table-para">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.</p><a name="447"></a><a name="IDX-273"></a></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">45</p></td> <td class="td" align="left"> <p class="table-para">brk</p></td> <td class="td" align="left"> <p class="table-para">new system break</p></td> <td class="td" align="left"> </td> <td class="td" align="left"> </td> <td class="td" align="left"> <p class="table-para">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.</p></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">54</p></td> <td class="td" align="left"> <p class="table-para">ioctl</p></td> <td class="td" align="left"> <p class="table-para">file descriptor</p></td> <td class="td" align="left"> <p class="table-para">request</p></td> <td class="td" align="left"> <p class="table-para">arguments</p></td> <td class="td" align="left"> <p class="table-para">This is used to set parameters on device files. Its actual usage varies based on the type of file or device your descriptor references.</p></td></tr></tbody></table> <p class="para">A more complete listing of system calls, along with additional information is available at <a class="url" href="http://www.lxhp.in-berlin.de/lhpsyscal.html" target="_top">http://www.lxhp.in-berlin.de/lhpsyscal.html</a> You can also get more information about a system call by typing in <span class="fixed">man 2 SYSCALLNAME</span> 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.</p> <p class="para">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 <a class="url" href="http://www.faqs.org/docs/kernel_2_4/lki-2.html#ss2.11" target="_top">http://www.faqs.org/docs/kernel_2_4/lki-2.html#ss2.11</a> </p><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8901974503278002812-3656164337444026863?l=programminggroundup.blogspot.com'/></div>Adminhttp://www.blogger.com/profile/13783659974416042562noreply@blogger.com0tag:blogger.com,1999:blog-8901974503278002812.post-76123006355390703472007-01-31T19:37:00.000-08:002007-01-31T19:40:46.164-08:00Appendix B: Common x86 Instructions<div class="section"> <h2 class="sect2-title"><a name="417"></a><a name="ap02lev1sec1"></a>Reading the Tables</h2> <p class="first-para">The tables of instructions presented in this appendix include:</p> <ul class="itemizedlist"><li class="first-listitem"> <p class="first-para">The instruction code</p> </li><li class="listitem"> <p class="first-para">The operands used</p> </li><li class="listitem"> <p class="first-para">The flags used</p> </li><li class="listitem"> <p class="first-para">A brief description of what the instruction does</p></li></ul> <p class="para">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 <span class="fixed">movl</span> instruction is listed as <span class="fixed">I/R/M</span>, <span class="fixed">R/M</span>. 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.</p> <p class="para">In the flags section, it lists the flags in the <span class="fixed">%eflags</span> register affected by the instruction. The following flags are mentioned:</p> <p class="para">O</p> <ul class="simple-list"><li class="first-listitem"> <p class="first-para">Overflow flag. This is set to true if the destination operand was not large enough to hold the result of the instruction.</p></li></ul> <p class="para">S</p> <ul class="simple-list"><li class="first-listitem"> <p class="first-para">Sign flag. This is set to the sign of the last result.</p></li></ul><a name="418"></a><a name="IDX-258"></a> <p class="para">Z</p> <ul class="simple-list"><li class="first-listitem"> <p class="first-para">Zero flag. This flag is set to true if the result of the instruction is zero.</p></li></ul> <p class="para">A</p> <ul class="simple-list"><li class="first-listitem"> <p class="first-para">Auxiliary carry flag. This flag is set for carries and borrows between the third and fourth bit. It is not often used.</p></li></ul> <p class="para">P</p> <ul class="simple-list"><li class="first-listitem"> <p class="first-para">Parity flag. This flag is set to true if the low byte of the last result had an even number of 1 bits.</p></li></ul> <p class="para">C</p> <ul class="simple-list"><li class="first-listitem"> <p class="first-para">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).</p></li></ul> <p class="last-para">Other flags exist, but they are much less important.</p><div class="appendix"><a name="ap02"></a> <div class="section"> <h2 class="first-section-title"><a name="419"></a><a name="ap02lev1sec2"></a>Data Transfer Instructions</h2> <p class="first-para">These instructions perform little, if any computation. Instead they are mostly used for moving data from one place to another.</p><a name="420"></a><a name="ap02table01"></a> <table class="table" border="1"> <caption class="table-title"><span class="table-title"><span class="table-titlelabel">Table B-1: </span>Data Transfer Instructions</span> </caption> <thead> <tr valign="top"> <th class="th" scope="col" align="left"> <p class="table-para"><b class="bold">Instruction</b> </p></th> <th class="th" scope="col" align="left"> <p class="table-para"><b class="bold">Operands</b> </p></th> <th class="th" scope="col" align="left"> <p class="table-para"><b class="bold">Affected Flags</b> </p></th></tr></thead> <tbody> <tr valign="top"> <td class="td" align="left"> <p class="table-para">movl</p></td> <td class="td" align="left"> <p class="table-para">I/R/M, I/R/M</p></td> <td class="td" align="left"> <p class="table-para">O/S/Z/A/C</p></td></tr> <tr valign="top"> <td class="td" colspan="3" align="left" valign="top"> <p class="table-para">This copies a word of data from one location to another. <span class="fixed">movl %eax</span>, <span class="fixed">%ebx</span> copies the contents of <span class="fixed">%eax</span> to <span class="fixed">%ebx</span> </p><a name="421"></a><a name="IDX-259"></a></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">movb</p></td> <td class="td" align="left"> <p class="table-para">I/R/M, I/R/M</p></td> <td class="td" align="left"> <p class="table-para">O/S/Z/A/C</p></td></tr> <tr valign="top"> <td class="td" colspan="3" align="left" valign="top"> <p class="table-para">Same as <span class="fixed">movl</span>, but operates on individual bytes.</p></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">leal</p></td> <td class="td" align="left"> <p class="table-para">M, I/R/M</p></td> <td class="td" align="left"> <p class="table-para">O/S/Z/A/C</p></td></tr> <tr valign="top"> <td class="td" colspan="3" align="left" valign="top"> <p class="table-para">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, <span class="fixed">leal 5 (%ebp, %ecx, 1), %eax</span> loads the address computed by <span class="fixed">5 + %ebp + 1*%ecx</span> and stores that in <span class="fixed">%eax</span> </p></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">popl</p></td> <td class="td" align="left"> <p class="table-para">R/M</p></td> <td class="td" align="left"> <p class="table-para">O/S/Z/A/C</p></td></tr> <tr valign="top"> <td class="td" colspan="3" align="left" valign="top"> <p class="table-para">Pops the top of the stack into the given location. This is equivalent to performing <span class="fixed">movl (%esp), R/M</span> followed by <span class="fixed">addl $4, %esp.popfl</span> is a variant which pops the top of the stack into the <span class="fixed">%eflags</span> register.</p></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">pushl</p></td> <td class="td" align="left"> <p class="table-para">I/R/M</p></td> <td class="td" align="left"> <p class="table-para">O/S/Z/A/C</p></td></tr> <tr valign="top"> <td class="td" colspan="3" align="left" valign="top"> <p class="table-para">Pushes the given value onto the stack. This is the equivalent to performing <span class="fixed">subl $4, %esp</span> followed by <span class="fixed">movl I/R/M, (%esp).pushfl</span> is a variant which pushes the current contents of the <span class="fixed">%eflags</span> register onto the <b class="bold">top</b> of the stack.</p></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">xchgl</p></td> <td class="td" align="left"> <p class="table-para">R/M, R/M</p></td> <td class="td" align="left"> <p class="table-para">O/S/Z/A/C</p></td></tr> <tr valign="top"> <td class="td" colspan="3" align="left" valign="top"> <p class="table-para">Exchange the values of the given operands.</p></td></tr></tbody></table></div></div><br /><div class="appendix"><a name="ap02"></a> <div class="section"> <h2 class="first-section-title"><a name="422"></a><a name="ap02lev1sec3"></a>Integer Instructions</h2> <p class="first-para">These are basic calculating instructions that operate on signed or unsigned integers.</p><a name="423"></a><a name="ap02table02"></a> <table class="table" border="1"> <caption class="table-title"><span class="table-title"><span class="table-titlelabel">Table B-2: </span>Integer Instructions</span> </caption> <thead> <tr valign="top"> <th class="th" scope="col" align="left"> <p class="table-para"><b class="bold">Instruction</b> </p></th> <th class="th" scope="col" align="left"> <p class="table-para"><b class="bold">Operands</b> </p></th> <th class="th" scope="col" align="left"> <p class="table-para"><b class="bold">Affected Flags</b> </p></th></tr></thead> <tbody> <tr valign="top"> <td class="td" align="left"> <p class="table-para">adcl</p></td> <td class="td" align="left"> <p class="table-para">I/R/M, R/M</p></td> <td class="td" align="left"> <p class="table-para">O/S/Z/A/P/C</p><a name="424"></a><a name="IDX-260"></a></td></tr> <tr valign="top"> <td class="td" colspan="3" align="left" valign="top"> <p class="table-para">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 <span class="fixed">addl</span>, while additions to the other words would used the <span class="fixed">adcl</span> instruction to take the carry from the previous add into account. For the usual case, this is not used, and <span class="fixed">addl</span> is used instead.</p></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">addl</p></td> <td class="td" align="left"> <p class="table-para">I/R/M, R/M</p></td> <td class="td" align="left"> <p class="table-para">O/S/Z/A/P/C</p></td></tr> <tr valign="top"> <td class="td" colspan="3" align="left" valign="top"> <p class="table-para">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.</p></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">cdq</p></td> <td class="td" align="left"> </td> <td class="td" align="left"> <p class="table-para">O/S/Z/A/P/C</p></td></tr> <tr valign="top"> <td class="td" colspan="3" align="left" valign="top"> <p class="table-para">Converts the <span class="fixed">%eax</span> word into the double-word consisting of <span class="fixed">%edx:%eax</span> with sign extension. The <span class="fixed">q</span> signifies that it is a <i class="emphasis">quad-word.</i> 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 <span class="fixed">idivl</span> instruction.</p></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">cmpl</p></td> <td class="td" align="left"> <p class="table-para">I/R/M, R/M</p></td> <td class="td" align="left"> <p class="table-para">O/S/Z/A/P/C</p></td></tr> <tr valign="top"> <td class="td" colspan="3" align="left" valign="top"> <p class="table-para">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.</p></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">decl</p></td> <td class="td" align="left"> <p class="table-para">R/M</p></td> <td class="td" align="left"> <p class="table-para">O/S/Z/A/P</p></td></tr> <tr valign="top"> <td class="td" colspan="3" align="left" valign="top"> <p class="table-para">Decrements the register or memory location. Use <span class="fixed">decb</span> to decrement a byte instead of a word.</p></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">divl</p></td> <td class="td" align="left"> <p class="table-para">R/M</p></td> <td class="td" align="left"> <p class="table-para">O/S/Z/A/P</p></td></tr> <tr valign="top"> <td class="td" colspan="3" align="left" valign="top"> <p class="table-para">Performs unsigned division. Divides the contents of the double-word contained in the combined <span class="fixed">%edx:%eax</span> registers by the value in the register or memory location specified. The <span class="fixed">%eax</span> register contains the resulting quotient, and the <span class="fixed">%edx</span> register contains the resulting remainder. If the quotient is too large to fit in <span class="fixed">%eax</span>, it triggers a type 0 interrupt.</p></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">idivl</p></td> <td class="td" align="left"> <p class="table-para">R/M</p></td> <td class="td" align="left"> <p class="table-para">O/S/Z/A/P</p><a name="425"></a><a name="IDX-261"></a></td></tr> <tr valign="top"> <td class="td" colspan="3" align="left" valign="top"> <p class="table-para">Performs signed division. Operates just like <span class="fixed">divl</span> above.</p></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">imull</p></td> <td class="td" align="left"> <p class="table-para">R/M/I, R</p></td> <td class="td" align="left"> <p class="table-para">O/S/Z/A/P/C</p></td></tr> <tr valign="top"> <td class="td" colspan="3" align="left" valign="top"> <p class="table-para">Performs signed multiplication and stores the result in the second operand. If the second operand is left out, it is assumed to be <span class="fixed">%eax</span>, and the full result is stored in the double-word <span class="fixed">%edx:%eax</span>.</p></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">incl</p></td> <td class="td" align="left"> <p class="table-para">R/M</p></td> <td class="td" align="left"> <p class="table-para">O/S/Z/A/P</p></td></tr> <tr valign="top"> <td class="td" colspan="3" align="left" valign="top"> <p class="table-para">Increments the given register or memory location. Use <span class="fixed">incb</span> to increment a byte instead of a word.</p></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">mull</p></td> <td class="td" align="left"> <p class="table-para">R/M/I, R</p></td> <td class="td" align="left"> <p class="table-para">O/S/Z/A/P/C</p></td></tr> <tr valign="top"> <td class="td" colspan="3" align="left" valign="top"> <p class="table-para">Perform unsigned multiplication. Same rules as apply to <span class="fixed">imull</span>.</p></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">negl</p></td> <td class="td" align="left"> <p class="table-para">R/M</p></td> <td class="td" align="left"> <p class="table-para">O/S/Z/A/P/C</p></td></tr> <tr valign="top"> <td class="td" colspan="3" align="left" valign="top"> <p class="table-para">Negates (gives the two's complement inversion of) the given register or memory location.</p></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">sbbl</p></td> <td class="td" align="left"> <p class="table-para">I/R/M, R/M</p></td> <td class="td" align="left"> <p class="table-para">O/S/Z/A/P/C</p></td></tr> <tr valign="top"> <td class="td" colspan="3" align="left" valign="top"> <p class="table-para">Subtract with borrowing. This is used in the same way that <span class="fixed">adc</span> is, except for subtraction. Normally only <span class="fixed">subl</span> is used.</p></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">subl</p></td> <td class="td" align="left"> <p class="table-para">I/R/M, R/M</p></td> <td class="td" align="left"> <p class="table-para">O/S/Z/A/P/C</p></td></tr> <tr valign="top"> <td class="td" colspan="3" align="left" valign="top"> <p class="table-para">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.</p></td></tr></tbody></table></div></div><br /><div class="appendix"><a name="ap02"></a> <div class="section"> <h2 class="first-section-title"><a name="426"></a><a name="ap02lev1sec4"></a>Logic Instructions</h2> <p class="first-para">These instructions operate on memory as bits instead of words.</p><a name="427"></a><a name="ap02table03"></a> <table class="table" border="1"> <caption class="table-title"><span class="table-title"><span class="table-titlelabel">Table B-3: </span>Logic Instructions</span> </caption> <thead> <tr valign="top"> <th class="th" scope="col" align="left"> <p class="table-para"><b class="bold">Instruction</b> </p></th> <th class="th" scope="col" align="left"> <p class="table-para"><b class="bold">Operands</b> </p></th> <th class="th" scope="col" align="left"> <p class="table-para"><b class="bold">Affected Flags</b> </p></th></tr></thead> <tbody> <tr valign="top"> <td class="td" align="left"> <p class="table-para">andl</p></td> <td class="td" align="left"> <p class="table-para">I/R/M, R/M</p></td> <td class="td" align="left"> <p class="table-para">O/S/Z/P/C</p></td></tr> <tr valign="top"> <td class="td" colspan="3" align="left" valign="top"> <p class="table-para">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.</p></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">notl</p></td> <td class="td" align="left"> <p class="table-para">R/M</p></td> <td class="td" align="left"> </td></tr> <tr valign="top"> <td class="td" colspan="3" align="left" valign="top"> <p class="table-para">Performs a logical not on each bit in the operand. Also known as a one's complement.</p></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">orl</p></td> <td class="td" align="left"> <p class="table-para">I/R/M, R/M</p></td> <td class="td" align="left"> <p class="table-para">O/S/Z/A/P/C</p></td></tr> <tr valign="top"> <td class="td" colspan="3" align="left" valign="top"> <p class="table-para">Performs a logical or between the two operands, and stores the result in the second operand. Sets the overflow and carry flags to false.</p></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">rcll</p></td> <td class="td" align="left"> <p class="table-para">I/<span class="fixed">%c1</span>, R/M</p></td> <td class="td" align="left"> <p class="table-para">O/C</p></td></tr> <tr valign="top"> <td class="td" colspan="3" align="left" valign="top"> <p class="table-para">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 <span class="fixed">%cl</span>. The carry flag is included in the rotation, making it use 33 bits instead of 32. Also sets the overflow flag.</p></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">rcrl</p></td> <td class="td" align="left"> <p class="table-para">I/<span class="fixed">%cl</span>, R/M</p></td> <td class="td" align="left"> <p class="table-para">O/C</p></td></tr> <tr valign="top"> <td class="td" colspan="3" align="left" valign="top"> <p class="table-para">Same as above, but rotates right.</p></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">roll</p></td> <td class="td" align="left"> <p class="table-para">I/<span class="fixed">%cl</span>, R/M</p></td> <td class="td" align="left"> <p class="table-para">O/C</p></td></tr> <tr valign="top"> <td class="td" colspan="3" align="left" valign="top"> <p class="table-para">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 <span class="fixed">%cl</span> register.</p></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">rorl</p></td> <td class="td" align="left"> <p class="table-para">I/<span class="fixed">%cl</span>, R/M</p></td> <td class="td" align="left"> <p class="table-para">O/C</p></td></tr> <tr valign="top"> <td class="td" colspan="3" align="left" valign="top"> <p class="table-para">Same as above, but rotates right.</p></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">sall</p></td> <td class="td" align="left"> <p class="table-para">I/<span class="fixed">%cl</span>, R/M</p></td> <td class="td" align="left"> <p class="table-para">C</p></td></tr> <tr valign="top"> <td class="td" colspan="3" align="left" valign="top"> <p class="table-para">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 <span class="fixed">%cl</span> register.</p></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">sarl</p></td> <td class="td" align="left"> <p class="table-para">I/<span class="fixed">%cl</span>, R/M</p></td> <td class="td" align="left"> <p class="table-para">C</p><a name="428"></a><a name="IDX-262"></a></td></tr> <tr valign="top"> <td class="td" colspan="3" align="left" valign="top"> <p class="table-para">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 <span class="fixed">%cl</span> register.</p></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">shll</p></td> <td class="td" align="left"> <p class="table-para">I/<span class="fixed">%cl</span>, R/M</p></td> <td class="td" align="left"> <p class="table-para">C</p></td></tr> <tr valign="top"> <td class="td" colspan="3" align="left" valign="top"> <p class="table-para">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 <span class="fixed">%cl</span> register.</p></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">shrl</p></td> <td class="td" align="left"> <p class="table-para">I/<span class="fixed">%cl</span>, R/M</p></td> <td class="td" align="left"> <p class="table-para">C</p></td></tr> <tr valign="top"> <td class="td" colspan="3" align="left" valign="top"> <p class="table-para">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 <span class="fixed">%cl</span> register.</p></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">testl</p></td> <td class="td" align="left"> <p class="table-para">I/R/M, R/M</p></td> <td class="td" align="left"> <p class="table-para">O/S/Z/A/P/C</p></td></tr> <tr valign="top"> <td class="td" colspan="3" align="left" valign="top"> <p class="table-para">Does a logical and of both operands and discards the results, but sets the flags accordingly.</p></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">xorl</p></td> <td class="td" align="left"> <p class="table-para">I/R/M, R/M</p></td> <td class="td" align="left"> <p class="table-para">O/S/Z/A/P/C</p></td></tr> <tr valign="top"> <td class="td" colspan="3" align="left" valign="top"> <p class="table-para">Does an exclusive or on the two operands, and stores the result in the second operand. Sets the overflow and carry flags to false.</p></td></tr></tbody></table></div></div><br /><div class="appendix"><a name="ap02"></a> <div class="section"> <h2 class="first-section-title"><a name="429"></a><a name="ap02lev1sec5"></a>Flow Control Instructions</h2><a name="430"></a><a name="IDX-263"></a> <p class="para">These instructions may alter the flow of the program.</p><a name="431"></a><a name="ap02table04"></a> <table class="table" border="1"> <caption class="table-title"><span class="table-title"><span class="table-titlelabel">Table B-4: </span>Flow Control Instructions</span> </caption> <thead> <tr valign="top"> <th class="th" scope="col" align="left"> <p class="table-para"><b class="bold">Instruction</b> </p></th> <th class="th" scope="col" align="left"> <p class="table-para"><b class="bold">Operands</b> </p></th> <th class="th" scope="col" align="left"> <p class="table-para"><b class="bold">Affected Flags</b> </p></th></tr></thead> <tbody> <tr valign="top"> <td class="td" align="left"> <p class="table-para">call</p></td> <td class="td" align="left"> <p class="table-para">destination address</p></td> <td class="td" align="left"> <p class="table-para">O/S/Z/A/C</p><a name="432"></a><a name="IDX-264"></a></td></tr> <tr valign="top"> <td class="td" colspan="3" align="left" valign="top"> <p class="table-para">This pushes what would be the next value for <span class="fixed">%eip</span> 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, <span class="fixed">call *%eax</span> will call the function at the address in <span class="fixed">%eax</span>.</p></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">int</p></td> <td class="td" align="left"> <p class="table-para">I</p></td> <td class="td" align="left"> <p class="table-para">O/S/Z/A/C</p></td></tr> <tr valign="top"> <td class="td" colspan="3" align="left" valign="top"> <p class="table-para">Causes an interrupt of the given number. This is usually used for system calls and other kernel interfaces.</p></td></tr> <tr valign="top"> <td class="td" align="left" valign="center"> <p class="table-para">Jcc</p></td> <td class="td" align="left" valign="center"> <p class="table-para">destination address</p></td> <td class="td" align="left" valign="center"> <p class="table-para">O/S/Z/A/C</p><a name="433"></a><a name="IDX-265"></a></td></tr> <tr valign="top"> <td class="td" colspan="3" align="left" valign="top"> <p class="table-para">Conditional branch. <span class="fixed">cc</span> is the <i class="emphasis">condition code.</i> 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:</p> <ul class="itemizedlist"><li class="first-listitem"> <p class="table-para"><span class="fixed">[n] a [e]</span> - above (unsigned greater than). An <span class="fixed">n</span> can be added for "not" and an <span class="fixed">e</span> can be added for "or equal to"</p> </li><li class="listitem"> <p class="table-para"><span class="fixed">[n] b [e]</span> - below (unsigned less than)</p> </li><li class="listitem"> <p class="table-para"><span class="fixed">[n] e</span> - equal to</p> </li><li class="listitem"> <p class="table-para"><span class="fixed">[n]z</span> - zero</p> </li><li class="listitem"> <p class="table-para"><span class="fixed">[n] g [e]</span> - greater than (signed comparison)</p> </li><li class="listitem"> <p class="table-para"><span class="fixed">[n] l [e]</span> - less than (signed comparison)</p> </li><li class="listitem"> <p class="table-para"><span class="fixed">[n] c</span> - carry flag set</p> </li><li class="listitem"> <p class="table-para"><span class="fixed">[n] o</span> - overflow flag set</p> </li><li class="listitem"> <p class="table-para"><span class="fixed">[p] p</span> - parity flag set</p> </li><li class="listitem"> <p class="table-para"><span class="fixed">[n] s</span> - sign flag set</p> </li><li class="listitem"> <p class="table-para"><span class="fixed">ecxz</span> - <span class="fixed">%ecx</span> is zero</p></li></ul></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">jmp</p></td> <td class="td" align="left"> <p class="table-para">destination address</p></td> <td class="td" align="left"> <p class="table-para">O/S/Z/A/C</p></td></tr> <tr valign="top"> <td class="td" colspan="3" align="left" valign="top"> <p class="table-para">An unconditional jump. This simply sets <span class="fixed">%eip</span> to the destination address. Alternatively, the destination address can be an asterisk followed by a register for an indirect jump. For example, <span class="fixed">jmp *%eax</span> will jump to the address in <span class="fixed">%eax</span>.</p><a name="434"></a><a name="IDX-266"></a></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">ret</p></td> <td class="td" align="left"> </td> <td class="td" align="left"> <p class="table-para">O/S/Z/A/C</p></td></tr> <tr valign="top"> <td class="td" colspan="3" align="left" valign="top"> <p class="table-para">Pops a value off of the stack and then sets <span class="fixed">%eip</span> to that value. Used to return from function calls.</p></td></tr></tbody></table></div></div><br /><div class="appendix"><a name="ap02"></a> <div class="section"> <h2 class="first-section-title"><a name="435"></a><a name="ap02lev1sec6"></a>Assembler Directives</h2> <p class="first-para">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.</p><a name="436"></a><a name="ap02table05"></a> <table class="table" border="1"> <caption class="table-title"><span class="table-title"><span class="table-titlelabel">Table B-5: </span>Assembler Directives</span> </caption> <thead> <tr valign="top"> <th class="th" scope="col" align="left"> <p class="table-para"><b class="bold">Directive</b> </p></th> <th class="th" scope="col" align="left"> <p class="table-para"><b class="bold">Operands</b> </p></th> <th class="th" scope="col" align="left"> </th></tr></thead> <tbody> <tr valign="top"> <td class="td" align="left"> <p class="table-para">.ascii</p></td> <td class="td" align="left"> <p class="table-para">QUOTED STRING</p></td> <td class="td" align="left"> </td></tr> <tr valign="top"> <td class="td" colspan="3" align="left" valign="top"> <p class="table-para">Takes the given quoted string and converts it into byte data.</p></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">.byte</p></td> <td class="td" align="left"> <p class="table-para">ALLIESVALUES</p></td> <td class="td" align="left"> </td></tr> <tr valign="top"> <td class="td" colspan="3" align="left" valign="top"> <p class="table-para">Takes a comma-separated list of values and inserts them right there in the program as data.</p></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">.endr</p></td> <td class="td" align="left"> </td> <td class="td" align="left"> </td></tr> <tr valign="top"> <td class="td" colspan="3" align="left" valign="top"> <p class="table-para">Ends a repeating section defined with <span class="fixed">.rept</span>.</p></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">.equ</p></td> <td class="td" align="left"> <p class="table-para">LABEL, VALUE</p></td> <td class="td" align="left"> </td></tr> <tr valign="top"> <td class="td" colspan="3" align="left" valign="top"> <p class="table-para">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.</p></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">.globl</p></td> <td class="td" align="left"> <p class="table-para">LABEL</p></td> <td class="td" align="left"> </td></tr> <tr valign="top"> <td class="td" colspan="3" align="left" valign="top"> <p class="table-para">Sets the given label as global, meaning that it can be used from separately-compiled object files.</p></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">.include</p></td> <td class="td" align="left"> <p class="table-para">FILE</p></td> <td class="td" align="left"> <a name="437"></a><a name="IDX-267"></a></td></tr> <tr valign="top"> <td class="td" colspan="3" align="left" valign="top"> <p class="table-para">Includes the given file just as if it were typed in right there.</p></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">.lcomm</p></td> <td class="td" align="left"> <p class="table-para">SYMBOL, SIZE</p></td> <td class="td" align="left"> </td></tr> <tr valign="top"> <td class="td" colspan="3" align="left" valign="top"> <p class="table-para">This is used in the <span class="fixed">.bss</span> 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.</p></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">.long</p></td> <td class="td" align="left"> <p class="table-para">VALUES</p></td> <td class="td" align="left"> </td></tr> <tr valign="top"> <td class="td" colspan="3" align="left" valign="top"> <p class="table-para">Takes a sequence of numbers separated by commas, and inserts those numbers as 4-byte words right where they are in the program.</p></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">.rept</p></td> <td class="td" align="left"> <p class="table-para">COUNT</p></td> <td class="td" align="left"> </td></tr> <tr valign="top"> <td class="td" colspan="3" align="left" valign="top"> <p class="table-para">Repeats everything between this directive and the <span class="fixed">.endr</span> directives the number of times specified.</p></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">.section</p></td> <td class="td" align="left"> <p class="table-para">SECTION NAME</p></td> <td class="td" align="left"> </td></tr> <tr valign="top"> <td class="td" colspan="3" align="left" valign="top"> <p class="table-para">Switches the section that is being worked on. Common sections include <span class="fixed">.text</span> (for code), <span class="fixed">.data</span> (for data embedded in the program itself), and <span class="fixed">.bss</span> (for uninitialized global data).</p></td></tr> <tr valign="top"> <td class="td" align="left"> <p class="table-para">.type</p></td> <td class="td" align="left"> <p class="table-para">SYMBOL, @function</p></td> <td class="td" align="left"> </td></tr> <tr valign="top"> <td class="td" colspan="3" align="left" valign="top"> <p class="table-para">Tells the linker that the given symbol is a function.</p></td></tr></tbody></table></div></div><br /><div class="section"> <h2 class="first-section-title"><a name="438"></a><a name="ap02lev1sec7"></a>Differences in Other Syntaxes and Terminology</h2> <p class="first-para">The syntax for assembly language used in this book is known at the <i class="emphasis">AT&T</i> 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:</p> <ul class="itemizedlist"><li class="first-listitem"> <p class="first-para">In Intel syntax, the operands of instructions are often reversed. The destination operand is listed before the source operand.</p><a name="439"></a><a name="IDX-268"></a> </li><li class="listitem"> <p class="first-para">In Intel syntax, registers are not prefixed with the percent sign (<span class="fixed">%</span>).</p> </li><li class="listitem"> <p class="first-para">In Intel syntax, a dollar-sign (<span class="fixed">$</span>) is not required to do immediate-mode addressing. Instead, non-immediate addressing is accomplished by surrounding the address with brackets (<span class="fixed">[]</span>).</p> </li><li class="listitem"> <p class="first-para">In Intel syntax, the instruction name does not include the size of data being moved. If that is ambiguous, it is explicitly stated as <span class="fixed">BYTE</span>, <span class="fixed">WORD</span>, Or <span class="fixed">DWORD</span> immediately after the instruction name.</p> </li><li class="listitem"> <p class="first-para">The way that memory addresses are represented in Intel assembly language is much different (shown below).</p> </li><li class="listitem"> <p class="first-para">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 - <span class="fixed">DWORD</span> stands for "double word" in Intel syntax and is used for standard-sized registers, which we would call simply a "word".</p> </li><li class="listitem"> <p class="first-para">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.</p></li></ul> <p class="para">Other differences exist, but they are small in comparison. To show some of the differences, consider the following instruction:</p> <div class="informalexample"><pre class="literallayout">movl %eax, 8(%ebx,%edi,4)<br /></pre></div> <p class="para">In Intel syntax, this would be written as:</p> <div class="informalexample"><pre class="literallayout">mov [8 + %ebx + 1 * edi], eax<br /></pre></div> <p class="last-para">The memory reference is a bit easier to read than its AT&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.</p><div class="section"> <h2 class="first-section-title"><a name="440"></a><a name="ap02lev1sec8"></a>Where to Go for More Information</h2><a name="441"></a><a name="IDX-269"></a> <p class="para">Intel has a set of comprehensive guides to their processors. These are available at <a class="url" href="http://www.intel.com/design/pentium/manuals/" target="_top">http://www.intel.com/design/pentium/manuals/</a> Note that all of these use the Intel syntax, not the AT&T syntax. The most important ones are their <i>IA-32 Intel Architecture Software Developer's Manual</i> in its three volumes::</p> <ul class="itemizedlist"><li class="first-listitem"> <p class="first-para"><i>Volume 1: System Programming Guide</i> </p> <p class="last-para">(<a class="url" href="http://developer.intel.com/design/pentium4/manuals/245470.htm" target="_top">http://developer.intel.com/design/pentium4/manuals/245470.htm</a>)</p> </li><li class="listitem"> <p class="first-para"><i>Volume 2: Instruction Set Reference</i> </p> <p class="last-para">(<a class="url" href="http://developer.intel.com/design/pentium4/manuals/245471.htm" target="_top">http://developer.intel.com/design/pentium4/manuals/245471.htm</a>)</p> </li><li class="listitem"> <p class="first-para"><i>Volume 3: System Programming Guide</i> </p> <p class="last-para">(<a class="url" href="http://developer.intel.com/design/pentium4/manuals/245472.htm" target="_top">http://developer.intel.com/design/pentium4/manuals/245472.htm</a>)</p></li></ul> <p class="para">In addition, you can find a lot of information in the manual for the GNU assembler, available online at <a class="url" href="http://www.gnu.org/software/binutils/manual/gas-2.9.1/as.html" target="_top">http://www.gnu.org/software/binutils/manual/gas-2.9.1/as.html</a>. Similarly, the manual for the GNU linker is available online at <a class="url" href="http://www.gnu.org/software/binutils/manual/ld-2.9.1/ld.html" target="_top">http://www.gnu.org/software/binutils/manual/ld-2.9.1/ld.html</a>.</p><a name="442"></a><a name="IDX-270"></a></div></div><br /></div><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8901974503278002812-7612300635539070347?l=programminggroundup.blogspot.com'/></div>Adminhttp://www.blogger.com/profile/13783659974416042562noreply@blogger.com0tag:blogger.com,1999:blog-8901974503278002812.post-32912703049119431962007-01-31T19:35:00.000-08:002007-01-31T19:37:33.803-08:00Appendix A: GUI Programming<div class="section"> <h2 class="sect2-title"><a name="394"></a><a name="ap01lev1sec1"></a>Introduction to GUI Programming</h2> <p class="first-para">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.</p><h2 class="first-section-title"><a name="395"></a><a name="ap01lev1sec2"></a>The GNOME Libraries</h2> <p class="first-para">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.</p> <p class="para">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 <i class="emphasis">opaque</i> - 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.</p><a name="396"></a><a name="IDX-240"></a> <p class="last-para">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 <a class="url" href="http://developer.gnome.org/" target="_top">http://developer.gnome.org/</a>. This site contains tutorials, mailing lists, API documentation, and everything else you need to start programming in the GNOME environment.</p><h2 class="first-section-title"><a name="397"></a><a name="ap01lev1sec3"></a>A Simple GNOME Program in Several Languages</h2> <p class="first-para">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</p> <div class="informalexample"><pre class="literallayout">gnome-example.s:<br /><br />#PURPOSE: This program is meant to be an example<br /># of what GUI programs look like written<br /># with the GNOME libraries<br />#<br />#INPUT: The user can only click on the "Quit"<br /># button or close the window<br />#<br />#OUTPUT: The application will close<br />#<br />#PROCESS: If the user clicks on the "Quit" button,<br /># the program will display a dialog asking<br /># if they are sure. If they click Yes, it<br /># will close the application. Otherwise<br /># it will continue running<br />#<br /><br />.section .data<br /><br />###GNOME definitions - These were found in the GNOME<br /># header files for the C language<br /># and converted into their assembly<a name="398"></a><a name="IDX-241"></a><br /># equivalents<br /><br />#GNOME Button Names<br />GNOME_STOCK_BUTTON_YES:<br />.ascii "Button_Yes\0"<br />GNOME_STOCK_BUTTON_NO:<br />.ascii "Button_No\0"<br /><br />#Gnome MessageBox Types<br />GNOME_MESSAGE_BOX_QUESTION:<br />.ascii "question\0"<br /><br />#Standard definition of NULL<br />.equ NULL, 0<br /><br />#GNOME signal definitions<br />signal_destroy:<br />.ascii "destroy\0"<br />signal_delete_event:<br />.ascii "delete_event\0"<br />signal_clicked:<br />.ascii "clicked\0"<br /><br />###Application-specific definitions<br /><br />#Application information<br />app_id:<br />.ascii "gnome-example\0"<br />app_version:<br />.ascii "1.000\0"<br />app_title:<br />.ascii "Gnome Example Program\0"<br /><br />#Text for Buttons and windows<br />button_quit_text:<a name="399"></a><a name="IDX-242"></a><br />.ascii "I Want to Quit the GNOME Example Program\0"<br />quit_question:<br />.ascii "Are you sure you want to quit?\0"<br /><br /><br />.section .bss<br /><br />#Variables to save the created widgets in<br />.equ WORD_SIZE, 4<br />.lcomm appPtr, WORD_SIZE<br />.lcomm btnQuit, WORD_SIZE<br /><br />.section .text<br /><br />.globl main<br />.type main, @function<br />main:<br />pushl %ebp<br />movl %esp, %ebp<br /><br />#Initialize GNOME libraries<br />pushl 12(%ebp) #argv<br />pushl 8 (%ebp) #argc<br />pushl $app_version<br />pushl $app_id<br />call gnome_init<br />addl $16, %esp #recover the stack<br /><br />#Create new application window<br />pushl $app_title #Window title<br />pushl $app_id #Application ID<br />call gnome_app__new<br />addl $8, %esp #recover the stack<br />movl %eax, appPtr #save the window pointer<a name="400"></a><a name="IDX-243"></a><br />#Create new button<br />pushl $button_quit_text #button text<br />call gtk_button_new_with_label<br />addl $4, %esp #recover the stack<br />movl %eax, btnQuit #save the button pointer<br /><br />#Make the button show up inside the application window<br />pushl btnQuit<br />pushl appPtr<br />call gnome_app_set_contents<br />addl $8, %esp<br /><br />#Makes the button show up (only after it's window<br />#shows up, though)<br />pushl btnQuit<br />call gtk_widget_show<br />addl $4, %esp<br /><br />#Makes the application window show up<br />pushl appPtr<br />call gtk_widget_show<br />addl $4, %esp<br /><br />#Have GNOME call our delete_handler function<br />#whenever a "delete" event occurs<br />pushl $NULL #extra data to pass to our<br /> #function (we don't use any)<br />pushl $delete_handler #function address to call<br />pushl $signal_delete_event #name of the signal<br />pushl appPtr #widget to listen for events on<br />call gtk_signal_connect<br />addl $16, %esp #recover stack<br /><br />#Have GNOME call our destroy_handler function<br />#whenever a "destroy" event occurs<a name="401"></a><a name="IDX-244"></a><br />pushl $NULL #extra data to pass to our<br /> #function (we don't use any)<br />pushl $destroy_handler #function address to call<br />pushl $signal_destroy #name of the signal<br />pushl appPtr #widget to listen for events on<br />call gtk_signal_connect<br />addl $16, %esp #recover stack<br /><br />#Have GNOME call our click_handler function<br />#whenever a "click" event occurs. Note that<br />#the previous signals were listening on the<br />#application window, while this one is only<br />#listening on the button<br />pushl $NULL<br />pushl $click_handler<br />pushl $signal_clicked<br />pushl btnQuit<br />call gtk_signal_connect<br />addl $16, %esp<br /><br />#Transfer control to GNOME. Everything that<br />#happens from here out is in reaction to user<br />#events, which call signal handlers. This main<br />#function just sets up the main window and connects<br />#signal handlers, and the signal handlers take<br />#care of the rest<br />call gtk_main<br /><br />#After the program is finished, leave<br />movl $0, %eax<br />leave<br />ret<br /><br />#A "destroy" event happens when the widget is being<br />#removed. In this case, when the application window<a name="402"></a><a name="IDX-245"></a><br />#is being removed, we simply want the event loop to<br />#quit<br />destroy_handler:<br />pushl %ebp<br />movl %esp, %ebp<br /><br />#This causes gtk to exit it's event loop<br />#as soon as it can.<br />call gtk_main_quit<br /><br />movl $0, %eax<br />leave<br />ret<br /><br />#A "delete" event happens when the application window<br />#gets clicked in the "x" that you normally use to<br />#close a window<br />delete_handler:<br />movl $1, %eax<br />ret<br /><br />#A "click" event happens when the widget gets clicked<br />click_handler:<br />pushl %ebp<br />movl %esp, %ebp<br /><br />#Create the "Are you sure" dialog<br />pushl $NULL #End of buttons<br />pushl $GNOME_STOCK_BUTTON_NO #Button 1<br />pushl $GNOME_STOCK_BUTTON_YES #Button 0<br />pushl $GNOME_MESSAGE_BOX_QUESTION #Dialog type<br />pushl $quit_question #Dialog mesasge<br />call gnome_message_box_new<br />addl $16, %esp #recover stack<a name="403"></a><a name="IDX-246"></a><br />#%eax now holds the pointer to the dialog window<br /><br />#Setting Modal to 1 prevents any other user<br />#interaction while the dialog is being shown<br />pushl $1<br />pushl %eax<br />call gtk_window_set_modal<br />popl %eax<br />addl $4, %esp<br /><br />#Now we show the dialog<br />pushl %eax<br />call gtk_widget_show<br />popl %eax<br /><br />#This sets up all the necessary signal handlers<br />#in order to just show the dialog, close it when<br />#one of the buttons is clicked, and return the<br />#number of the button that the user clicked on.<br />#The button number is based on the order the buttons<br />#were pushed on in the gnome_message_box_new function<br />pushl %eax<br />call gnome_dialog_run_and_close<br />addl $4, %esp<br /><br />#Button 0 is the Yes button. If this is the<br />#button they clicked on, tell GNOME to quit<br />#it's event loop. Otherwise, do nothing<br />cmpl $0, %eax<br />jne click_handler_end<br /><br />call gtk_main_quit<br /><br />click_handler_end:<br />leave<a name="404"></a><a name="IDX-247"></a><br />ret<br /></pre></div> <p class="para">To build this application, execute the following commands:</p> <div class="informalexample"><pre class="literallayout">as gnome-example.s -o gnome-example.o<br />gcc gnome-example.o 'gnome-config --libs gnomeui' \<br /> -o gnome-example<br /></pre></div> <p class="para">Then type in <span class="fixed">./gnome-example</span> to run it.</p> <p class="para">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 <i class="emphasis">callback</i> functions. All of the event processing is handled by the function <span class="fixed">gtk_main,</span> 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.</p> <p class="para">Here is a short description of all of the GNOME functions that were used in this program:</p> <p class="para">gnome_init</p> <ul class="simple-list"><li class="first-listitem"> <p class="first-para">Takes the command-line arguments, argument count, application id, and application version and initializes the GNOME libraries.</p></li></ul> <p class="para">gnome_app_new</p> <ul class="simple-list"><li class="first-listitem"> <p class="first-para">Creates a new application window, and returns a pointer to it. Takes the application id and the window title as arguments.</p></li></ul> <p class="para">gtk_button_new_with_label</p> <ul class="simple-list"><li class="first-listitem"> <p class="first-para">Creates a new button and returns a pointer to it. Takes one argument - the text that is in the button.</p></li></ul><a name="405"></a><a name="IDX-248"></a> <p class="para">gnome_app_set_contents</p> <ul class="simple-list"><li class="first-listitem"> <p class="first-para">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</p></li></ul> <p class="para">gtk_widget_show</p> <ul class="simple-list"><li class="first-listitem"> <p class="first-para">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.</p></li></ul> <p class="para">gtk_signal_connect</p> <ul class="simple-list"><li class="first-listitem"> <p class="first-para">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.</p></li></ul> <p class="para">gtk_main</p> <ul class="simple-list"><li class="first-listitem"> <p class="first-para">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 <span class="fixed">gtk_main_quit</span> is called by a signal handler.</p></li></ul> <p class="para">gtk_main_quit</p> <ul class="simple-list"><li class="first-listitem"> <p class="first-para">This function causes GNOME to exit its main loop at the earliest opportunity.</p></li></ul> <p class="para">gnome_message_box_new</p> <ul class="simple-list"><li class="first-listitem"> <p class="first-para">This function creates a dialog window containing a question and response <a name="406"></a><a name="IDX-249"></a>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.</p></li></ul> <p class="para">gtk_window_set_modal</p> <ul class="simple-list"><li class="first-listitem"> <p class="first-para">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.</p></li></ul> <p class="para">gnome_dialog_run_and_close</p> <ul class="simple-list"><li class="first-listitem"> <p class="first-para">This function takes a dialog pointer (the pointer returned by <span class="fixed">gnome_message_box_new</span> 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 <span class="fixed">gnome_message_box_new.</span> </p></li></ul> <p class="para">The following is the same program written in the C language. Type it in as <span class="fixed">gnome-example-c.c:</span> </p> <div class="informalexample"><pre class="literallayout">/* PURPOSE: This program is meant to be an example<br /> of what GUI programs look like written<br /> with the GNOME libraries<br />*/<br /><br />#include <gnome.h><br /><br />/* Program definitions */<br />#define MY_APP_TITLE "Gnome Example Program"<br />#define MY_APP_ID "gnome-example"<br />#define MY_APP_VERSION "1.000"<a name="407"></a><a name="IDX-250"></a><br />#define MY_BUTTON_TEXT "I Want to Quit the Example Program"<br />#define MY_QUIT_QUESTION "Are you sure you want to quit?"<br /><br />/* Must declare functions before they are used */<br />int destroy_handler(gpointer window,<br /> GdkEventAny *e,<br /> gpointer data);<br />int delete_handler(gpointer window,<br /> GdkEventAny *e,<br /> gpointer data);<br />int click__handler(gpointer window,<br /> GdkEventAny *e,<br /> gpointer data);<br /><br />int main(int argc, char **argv)<br />{<br />gpointer appPtr; /* application window */<br />gpointer btnQuit; /* quit button */<br /><br />/* Initialize GNOME libraries */<br />gnome_init(MY_APP_ID, MY_APP_VERSION, argc, argv);<br /><br />/* Create new application window */<br />appPtr = gnome_app_new(MY_APP_ID, MY_APP_TITLE);<br /><br />/* Create new button */<br />btnQuit = gtk_button_new_with_label(MY_BUTTON_TEXT);<br /><br />/* Make the button show up inside the application window */<br />gnome_app_set_contents(appPtr, btnQuit);<br /><br />/* Makes the button show up */<br />gtk_widget_show(btnQuit);<br /><br />/* Makes the application window show up */<a name="408"></a><a name="IDX-251"></a><br />gtk_widget_show(appPtr);<br /><br />/* Connect the signal handlers */<br />gtk_signal_connect(appPtr, "delete_event",<br /> GTK_SIGNAL_FUNC(delete_handler), NULL);<br />gtk_signal_connect(appPtr, "destroy",<br /> GTK_SIGNAL_FUNC(destroy_handler), NULL);<br />gtk_signal_connect(btnQuit, "clicked",<br /> GTK_SIGNAL_FUNC(click_handler), NULL);<br /><br />/* Transfer control to GNOME */<br />gtk_main();<br /><br />return 0;<br />}<br /><br />/* Function to receive the "destroy" signal */<br />int destroy_handler(gpointer window,<br /> GdkEventAny *e,<br /> gpointer data)<br />{<br />/* Leave GNOME event loop */<br />gtk_main_quit();<br />return 0;<br />}<br /><br />/* Function to receive the "delete_event" signal */<br />int delete_handler(gpointer window,<br /> GdkEventAny *e,<br /> gpointer data)<br />{<br />return 0;<br />}<a name="409"></a><a name="IDX-252"></a><br />/* Function to receive the "clicked" signal */<br />int click_handler(gpointer window,<br /> GdkEventAny *e,<br /> gpointer data)<br />{<br />gpointer msgbox;<br />int buttonClicked;<br /><br />/* Create the "Are you sure" dialog */<br />msgbox = gnome_message_box_new(<br /> MY_QUIT_QUESTION,<br /> GNOME_MESSAGE_BOX_QUESTION,<br /> GNOME_STOCK_BUTTON_YES,<br /> GNOME_STOCK_BUTTON_NO,<br /> NULL);<br />gtk_window_set_modal(msgbox, 1);<br />gtk_widget_show(msgbox);<br /><br />/* Run dialog box */<br />buttonClicked = gnome_dialog_run_and_close(msgbox);<br /><br />/* Button 0 is the Yes button. If this is the<br />button they clicked on, tell GNOME to quit<br />it's event loop. Otherwise, do nothing */<br />if(buttonClicked == 0)<br />{<br /> gtk_main_quit();<br />}<br /><br />return 0;<br />}<br /></pre></div> <p class="para">To compile it, type</p><a name="410"></a><a name="IDX-253"></a> <div class="informalexample"><pre class="literallayout">gcc gnome-example-c.c 'gnome-config --cflags \<br /> --libs gnomeui' -o gnome-example-c<br /></pre></div> <p class="para">Run it by typing <span class="fixed">./gnome-example-c.</span> </p> <p class="para">Finally, we have a version in Python. Type it in as gnome-example.py:</p> <div class="informalexample"><pre class="literallayout">#PURPOSE: This program is meant to be an example<br /># of what GUI programs look like written<br /># with the GNOME libraries<br />#<br /><br />#lmport GNOME libraries<br />import gtk<br />import gnome.ui<br /><br />####DEFINE CALLBACK FUNCTIONS FIRST####<br /><br />#In Python, functions have to be defined before<br />#they are used, so we have to define our callback<br />#functions first.<br /><br />def destroy_handler(event):<br />gtk.mainquit()<br />return 0<br /><br />def delete_handler(window, event):<br />return 0<br /><br />def click_handler(event):<br />#Create the "Are you sure" dialog<br />msgbox = gnome.ui.GnomeMessageBox(<br /> "Are you sure you want to quit?",<br /> gnome.ui.MESSAGE_BOX_QUESTION,<br /> gnome.ui.STOCK_BUTTON_YES,<br /> gnome.ui.STOCK_BUTTON_NO)<a name="411"></a><a name="IDX-254"></a><br />msgbox.set_modal(1)<br />msgbox.show()<br /><br />result = msgbox.run_and_close()<br /><br />#Button 0 is the Yes button. If this is the<br />#button they clicked on, tell GNOME to quit<br />#it's event loop. Otherwise, do nothing<br />if (result == 0):<br /> gtk.mainquit()<br /><br />return 0<br /><br />####MAIN PROGRAM####<br /><br />#Create new application window<br />myapp = gnome.ui.GnomeApp(<br />"gnome-example", "Gnome Example Program")<br /><br />#Create new button<br />mybutton = gtk.GtkButton(<br />"I Want to Quit the GNOME Example program")<br />myapp.set_contents(mybutton)<br /><br />#Makes the button show up<br />mybutton.show()<br /><br />#Makes the application window show up<br />myapp.show()<br /><br />#Connect signal handlers<br />myapp.connect("delete_event", delete_handler)<br />myapp.connect("destroy", destroy_handler)<br />mybutton.connect("clicked", click_handler)<a name="412"></a><a name="IDX-255"></a><br />#Transfer control to GNOME<br />gtk.mainloop()<br /></pre></div> <p class="last-para">To run it type <span class="fixed">python gnome-example .py.</span></p><div class="section"> <h2 class="first-section-title"><a name="413"></a><a name="ap01lev1sec4"></a>GUI Builders</h2> <p class="first-para">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.</p> <p class="para">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.</p> <p class="para">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.</p><a name="414"></a><a name="IDX-256"></a></div></div><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8901974503278002812-3291270304911943196?l=programminggroundup.blogspot.com'/></div>Adminhttp://www.blogger.com/profile/13783659974416042562noreply@blogger.com0tag:blogger.com,1999:blog-8901974503278002812.post-78337317826557159302007-01-31T19:29:00.000-08:002007-01-31T19:32:14.109-08:00Chapter 13: Moving on From Here<div class="section"> <h2 class="sect2-title"><a name="380"></a>Overview</h2><a name="381"></a><a name="IDX-233"></a> <p class="para">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.</p> <p class="para">There are essentially three methods to learn to program:</p> <ul class="itemizedlist"><li class="first-listitem"> <p class="first-para">From the Bottom Up - This is how this book teaches. It starts with low-level programming, and works toward more generalized teaching.</p> </li><li class="listitem"> <p class="first-para">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.</p> </li><li class="listitem"> <p class="first-para">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.</p></li></ul> <p class="para">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.</p> <p class="para">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 <i class="emphasis">thinking.</i> As Alan Perlis said, "A language that doesn't affect the way you think about programming is not worth knowing" (<a class="url" href="http://www.cs.yale.edu/homes/perlis-alan/quotes.html" target="_top">http://www.cs.yale.edu/homes/perlis-alan/quotes.html</a>). 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 <a name="382"></a><a name="IDX-234"></a>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.</p> <p class="last-para">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.</p><h2 class="first-section-title"><a name="383"></a><a name="ch13lev1sec1"></a>From the Bottom Up</h2> <p class="first-para">This list is in the best reading order I could find. It's not necessarily easiest to hardest, but based on subject matter.</p> <ul class="itemizedlist"><li class="first-listitem"> <p class="first-para"><i><a>Programming from the Ground Up</a></i> by Jonathan Bartlett</p> </li><li class="listitem"> <p class="first-para"><i><a>Introduction to Algorithms</a></i> by Thomas H. Cormen, Charles E. Leiserson, and Ronald L. Rivest</p> </li><li class="listitem"> <p class="first-para"><i>The Art of Computer Programming</i> by Donald Knuth (3 volume set - volume 1 is the most important)</p> </li><li class="listitem"> <p class="first-para"><i>Programming Languages</i> by Samuel N. Kamin</p> </li><li class="listitem"> <p class="first-para"><i>Modern Operating Systems</i> by Andrew Tanenbaum</p> </li><li class="listitem"> <p class="first-para"><i>Linkers and Loaders</i> by John Levine</p> </li><li class="listitem"> <p class="first-para"><i>Computer Organization and Design: The Hardware/Software Interface</i> by David Patterson and John Hennessy</p></li></ul><br /><div class="section"> <h2 class="first-section-title"><a name="384"></a><a name="ch13lev1sec2"></a>From the Top Down</h2> <p class="first-para">These books are arranged from the simplest to the hardest. However, they can be read in any order you feel comfortable with.</p><a name="385"></a><a name="IDX-235"></a> <ul class="itemizedlist"><li class="first-listitem"> <p class="first-para"><i>How to Design Programs</i> by Matthias Felleisen, Robert Bruce Findler, Matthew Flatt, and Shiram Krishnamurthi, available online at <a class="url" href="http://www.htdp.org/" target="_top">http://www.htdp.org/</a> </p> </li><li class="listitem"> <p class="first-para"><i>Simply Scheme: An Introduction to Computer Science</i> by Brian Harvey and Matthew Wright</p> </li><li class="listitem"> <p class="first-para"><i>How to Think Like a Computer Scientist: Learning with Python</i> by Allen Downey, Jeff Elkner, and Chris Meyers, available online at <a class="url" href="http://www.greenteapress.com/thinkpython/" target="_top">http://www.greenteapress.com/thinkpython/</a> </p> </li><li class="listitem"> <p class="first-para"><i>Structure and Interpretation of Computer Programs</i> by Harold Abelson and Gerald Jay Sussman with Julie Sussman, available online at <a class="url" href="http://mitpress.mit.edu/sicp/" target="_top">http://mitpress.mit.edu/sicp/</a> </p> </li><li class="listitem"> <p class="first-para"><i>Design Patterns</i> by Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides</p> </li><li class="listitem"> <p class="first-para"><i>What not How: The Rules Approach to Application Development</i> by Chris Date</p> </li><li class="listitem"> <p class="first-para"><i>The Algorithm Design Manual</i> by Steve Skiena</p> </li><li class="listitem"> <p class="first-para"><i>Programming Language Pragmatics</i> by Michael Scott</p> </li><li class="listitem"> <p class="first-para"><i>Essentials of Programming Languages</i> by Daniel P. Friedman, Mitchell Wand, and Christopher T. Haynes</p></li></ul><br /><div class="section"> <h2 class="first-section-title"><a name="386"></a><a name="ch13lev1sec3"></a>From the Middle Out</h2> <p class="first-para">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.</p> <ul class="itemizedlist"><li class="first-listitem"> <p class="first-para"><i>Programming Perl</i> by Larry Wall, Tom Christiansen, and Jon Orwant</p> </li><li class="listitem"> <p class="first-para"><i>Common LISP: The Language</i> by Guy R. Steele</p> </li><li class="listitem"> <p class="first-para"><i>ANSI Common LISP</i> by Paul Graham</p> </li><li class="listitem"> <p class="first-para"><i>The C Programming Language</i> by Brian W. Kernighan and Dennis M. Ritchie</p><a name="387"></a><a name="IDX-236"></a> </li><li class="listitem"> <p class="first-para"><i><a>The Waite Group's C Primer Plus</a></i> by Stephen Prata</p> </li><li class="listitem"> <p class="first-para"><i>The C++ Programming Language</i> by Bjarne Stroustrup</p> </li><li class="listitem"> <p class="first-para"><i>Thinking in Java</i> by Bruce Eckel, available online at <a class="url" href="http://www.mindview.net/Books/TIJ/" target="_top">http://www.mindview.net/Books/TIJ/</a> </p> </li><li class="listitem"> <p class="first-para"><i><a>The Scheme Programming Language</a></i> by Kent Dybvig</p> </li><li class="listitem"> <p class="first-para"><i>Linux Assembly Language Programming</i> by Bob Neveln</p></li></ul><br /><div class="chapter"><a name="ch13"></a> <div class="section"> <h2 class="first-section-title"><a name="388"></a><a name="ch13lev1sec4"></a>Specialized Topics</h2> <p class="first-para">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.</p> <ul class="itemizedlist"><li class="first-listitem"> <p class="first-para">Practical Programming - <i>Programming Pearls and More Programming Pearls</i> by Jon Louis Bentley</p> </li><li class="listitem"> <p class="first-para">Databases - <i>Understanding Relational Databases</i> by Fabian Pascal</p> </li><li class="listitem"> <p class="first-para">Project Management - <i>The Mythical Man-Month</i> by Fred P. Brooks</p> </li><li class="listitem"> <p class="first-para">UNIX Programming - <i>The Art of UNIX Programming</i> by Eric S. Raymond, available online at <a class="url" href="http://www.catb.org/%7Eesr/writings/taoup/" target="_top">http://www.catb.org/~esr/writings/taoup/</a> </p> </li><li class="listitem"> <p class="first-para">UNIX Programming - <i>Advanced Programming in the UNIX Environment</i> by W. Richard Stevens</p> </li><li class="listitem"> <p class="first-para">Network Programming - <i>UNIX Network Programming</i> (2 volumes) by W. Richard Stevens</p> </li><li class="listitem"> <p class="first-para">Generic Programming - <i>Modern C++ Design</i> by Andrei Alexandrescu</p> </li><li class="listitem"> <p class="first-para">Compilers - <i>The Art of Compiler Design: Theory and Practice</i> by Thomas Pittman and James Peters</p><a name="389"></a><a name="IDX-237"></a> </li><li class="listitem"> <p class="first-para">Compilers - <i>Advanced Compiler Design and Implementation</i> by Steven Muchnick</p> </li><li class="listitem"> <p class="first-para">Development Process - <i>Refactoring: Improving the Design of Existing Code</i> by Martin Fowler, Kent Beck, John Brant, William Opdyke, and Don Roberts</p> </li><li class="listitem"> <p class="first-para">Typesetting - <i>Computers and Typesetting</i> (5 volumes) by Donald Knuth</p> </li><li class="listitem"> <p class="first-para">Cryptography - <i>Applied Cryptography</i> by Bruce Schneier</p> </li><li class="listitem"> <p class="first-para">Linux - <i><a>Professional Linux Programming</a></i> by Neil Matthew, Richard Stones, and 14 other people</p> </li><li class="listitem"> <p class="first-para">Linux Kernel - <i>Linux Device Drivers</i> by Alessandro Rubini and Jonathan Corbet</p> </li><li class="listitem"> <p class="first-para">Open Source Programming - <i>The Cathedral and the Bazaar: Musings on Linux and Open Source by an Accidental Revolutionary</i> by Eric S. Raymond</p> </li><li class="listitem"> <p class="first-para">Computer Architecture - <i>Computer Architecture: A Quantitative Approach</i> by David Patterson and John Hennessy</p></li></ul></div></div><br /><h2 class="first-section-title"><a name="390"></a><a name="ch13lev1sec5"></a>Further Resources on Assembly Language</h2> <p class="first-para">In assembly language, your best resources are on the web.</p> <ul class="itemizedlist"><li class="first-listitem"> <p class="first-para"><a class="url" href="http://www.linuxassembly.org/" target="_top">http://www.linuxassembly.org/</a> - a great resource for Linux assembly language programmers</p> </li><li class="listitem"> <p class="first-para"><a class="url" href="http://www.sandpile.org/" target="_top">http://www.sandpile.org/</a> - a repository of reference material on x86, x86-64, and compatible processors</p> </li><li class="listitem"> <p class="first-para"><a class="url" href="http://www.x86.org/" target="_top">http://www.x86.org/</a> - Dr. Dobb's Journal Microprocessor Resources</p> </li><li class="listitem"> <p class="first-para"><a class="url" href="http://www.drpaulcarter.com/pcasm/" target="_top">http://www.drpaulcarter.com/pcasm/</a> - Dr. Paul Carter's PC Assembly Language Page</p> </li><li class="listitem"> <p class="first-para"><a class="url" href="http://webster.cs.ucr.edu/" target="_top">http://webster.cs.ucr.edu/</a> - The Art of Assembly Home Page</p><a name="391"></a><a name="IDX-238"></a> </li><li class="listitem"> <p class="first-para"><a class="url" href="http://www.intel.com/design/pentium/manuals/" target="_top">http://www.intel.com/design/pentium/manuals/</a> - Intel's manuals for their processors</p> </li><li class="listitem"> <p class="first-para"><a class="url" href="http://www.janw.easynet.be/" target="_top">http://www.janw.easynet.be/</a> - Jan Wagemaker's Linux assembly language examples</p> </li><li class="listitem"> <p class="first-para"><a class="url" href="http://www.azillionmonkeys.com/qed/asm.html" target="_top">http://www.azillionmonkeys.com/qed/asm.html</a> - Paul Hsieh's x86 Assembly Page</p></li></ul><br /></div></div><br /></div><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8901974503278002812-7833731782655715930?l=programminggroundup.blogspot.com'/></div>Adminhttp://www.blogger.com/profile/13783659974416042562noreply@blogger.com0tag:blogger.com,1999:blog-8901974503278002812.post-976030011522222012007-01-31T19:26:00.000-08:002007-01-31T19:29:16.261-08:00Chapter 12: Optimization<div class="highlights"> <p class="first-para">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.</p></div> <div class="section"> <h2 class="sect2-title"><a name="362"></a><a name="ch12lev1sec1"></a>When to Optimize</h2> <p class="first-para">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.</p> <p class="para">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 <i class="emphasis">Where to Optimize</i> will discuss how to find the parts of your program that need optimization.</p> <p class="para">While you develop your program, you need to have the following priorities:</p> <ul class="itemizedlist"><li class="first-listitem"> <p class="first-para">Everything is documented</p> </li><li class="listitem"> <p class="first-para">Everything works as documented</p> </li><li class="listitem"> <p class="first-para">The code is written in an modular, easily modifiable form</p></li></ul> <p class="para">Documentation is essential, especially when working in groups. The proper functioning of the program is essential. You'll notice application speed was not <a name="363"></a><a name="IDX-224"></a>anywhere on that list. Optimization is not necessary during early development for the following reasons:</p> <ul class="itemizedlist"><li class="first-listitem"> <p class="first-para">Minor speed problems can be usually solved through hardware, which is often much cheaper than a programmer's time.</p> </li><li class="listitem"> <p class="first-para">Your application will change dramatically as you revise it, therefore wasting most of your efforts to optimize it. <sup>[<a href="#ftn.N59" name="N59">1</a>]</sup> </p> </li><li class="listitem"> <p class="first-para">Speed problems are usually localized in a few places in your code - finding these is difficult before you have most of the program finished.</p></li></ul> <p class="para">Therefore, the time to optimize is toward the end of development, when you have determined that your correct code actually has performance problems.</p> <p class="last-para">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.</p></div> <div class="footnotes"> <div class="footnote"> <p><sup>[<a href="#N59" name="ftn.N59">1</a>]</sup>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.</p><h2 class="first-section-title"><a name="364"></a><a name="ch12lev1sec2"></a>Where to Optimize</h2> <p class="first-para">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 <i class="emphasis">profiler.</i> 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. <a name="365"></a><a name="IDX-225"></a><span class="fixed">gprof</span> 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.</p> <p class="para">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 <i class="emphasis">maximum</i> 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.</p> <p class="para">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.</p> <p class="last-para">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.</p><div class="section"> <h2 class="first-section-title"><a name="366"></a><a name="ch12lev1sec3"></a>Local Optimizations</h2> <p class="first-para">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.</p><a name="367"></a><a name="IDX-226"></a> <p class="para">Precomputing Calculations</p> <ul class="simple-list"><li class="first-listitem"> <p class="first-para">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.</p></li></ul> <p class="para">Remembering Calculation Results</p> <ul class="simple-list"><li class="first-listitem"> <p class="first-para">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 <i class="emphasis">caching</i> or <i class="emphasis">memoizing.</i> </p></li></ul> <p class="para">Locality of Reference</p> <ul class="simple-list"><li class="first-listitem"> <p class="first-para"><i class="emphasis">Locality of reference</i> 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. <a name="368"></a><a name="IDX-227"></a>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.</p></li></ul> <p class="para">Register Usage</p> <ul class="simple-list"><li class="first-listitem"> <p class="first-para">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.</p></li></ul> <p class="para">Inline Functions</p> <ul class="simple-list"><li class="first-listitem"> <p class="first-para">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.</p></li></ul><a name="369"></a><a name="IDX-228"></a> <p class="para">Optimized Instructions</p> <ul class="simple-list"><li class="first-listitem"> <p class="first-para">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 <span class="fixed">movl $0, %eax</span> is not the quickest way. The quickest way is to exclusive-or the register with itself, <span class="fixed">xorl %eax, %eax</span>. 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.</p></li></ul> <p class="para">Addressing Modes</p> <ul class="simple-list"><li class="first-listitem"> <p class="first-para">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.</p></li></ul> <p class="para">Data Alignment</p> <ul class="simple-list"><li class="first-listitem"> <p class="first-para">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.</p></li></ul> <p class="last-para">These are just a smattering of examples of the kinds of local optimizations possible. However, remember that the maintainability and readability of code is <a name="370"></a><a name="IDX-229"></a>much more important except under extreme circumstances.</p><div class="section"> <h2 class="first-section-title"><a name="371"></a><a name="ch12lev1sec4"></a>Global Optimization</h2> <p class="first-para">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.</p> <p class="para">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.</p> <p class="para">Global optimization usually often involves achieving the following properties in your functions:</p> <p class="para">Parallelization</p> <ul class="simple-list"><li class="first-listitem"> <p class="first-para">Parallelization means that your algorithm can effectively be split among multiple processes. For example, pregnancy is not very parallelizable because <a name="372"></a><a name="IDX-230"></a>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.</p></li></ul> <p class="para">Statelessness</p> <ul class="simple-list"><li class="first-listitem"> <p class="first-para">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.</p></li></ul> <p class="last-para">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.</p><div class="chapter"><a name="ch12"></a> <div class="section"> <h2 class="first-section-title"><a name="373"></a><a name="ch12lev1sec5"></a>Review</h2> <div class="section"> <h3 class="sect3-title"><a name="374"></a><a name="ch12lev2sec1"></a>Know the Concepts</h3> <ul class="itemizedlist"><li class="first-listitem"> <p class="first-para">At what level of importance is optimization compared to the other priorities in programming?</p> </li><li class="listitem"> <p class="first-para">What is the difference between local and global optimizations?</p> </li><li class="listitem"> <p class="first-para">Name some types of local optimizations.</p><a name="375"></a><a name="IDX-231"></a> </li><li class="listitem"> <p class="first-para">How do you determine what parts of your program need optimization?</p> </li><li class="listitem"> <p class="first-para">At what level of importance is optimization compared to the other priorities in programming? Why do you think I repeated that question?</p></li></ul></div> <div class="section"> <h3 class="sect3-title"><a name="376"></a><a name="ch12lev2sec2"></a>Use the Concepts</h3> <ul class="itemizedlist"><li class="first-listitem"> <p class="first-para">Go back through each program in this book and try to make optimizations according to the procedures outlined in this chapter</p> </li><li class="listitem"> <p class="first-para">Pick a program from the previous exercise and try to calculate the performance impact on your code under specific inputs. <sup>[<a href="#ftn.N54" name="N54">2</a>]</sup> </p></li></ul></div> <div class="section"> <h3 class="sect3-title"><a name="377"></a><a name="ch12lev2sec3"></a>Going Further</h3> <ul class="itemizedlist"><li class="first-listitem"> <p class="first-para">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.</p> </li><li class="listitem"> <p class="first-para">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 <span class="fixed">gprof</span> 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?</p> </li><li class="listitem"> <p class="first-para">Has the compiler eliminated the need for local optimizations? Why or why not?</p> </li><li class="listitem"> <p class="first-para">What kind of problems might a compiler run in to if it tried to optimize code across function call boundaries?</p></li></ul><a name="378"></a><a name="IDX-232"></a></div></div> <div class="footnotes"> <div class="footnote"> <p><sup>[<a href="#N54" name="ftn.N54">2</a>]</sup>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.</p></div></div></div></div></div></div></div><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8901974503278002812-97603001152222201?l=programminggroundup.blogspot.com'/></div>Adminhttp://www.blogger.com/profile/13783659974416042562noreply@blogger.com0tag:blogger.com,1999:blog-8901974503278002812.post-82368780616723519842007-01-31T19:22:00.000-08:002007-01-31T20:25:58.512-08:00Chapter 11: High-Level Languages<h2 class="sect2-title"><a name="341"></a>Overview</h2><a name="342"></a><a name="IDX-213"></a> <div class="highlights"> <p class="first-para">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</p> <ul class="itemizedlist"><li class="first-listitem"> <p class="first-para">Different languages are based on different concepts, which will help you to learn different and better programming methods and ideas.</p> </li><li class="listitem"> <p class="first-para">Different languages are good for different types of projects.</p> </li><li class="listitem"> <p class="first-para">Different companies have different standard languages, so knowing more languages makes your skills more marketable.</p> </li><li class="listitem"> <p class="first-para">The more languages you know, the easier it is to pick up new ones.</p></li></ul> <p class="last-para">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.</p><div class="section"> <h2 class="first-section-title"><a name="343"></a><a name="ch11lev1sec1"></a>Compiled and Interpreted Languages</h2> <p class="first-para">Many languages are <i class="emphasis">compiled</i> 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 <a name="344"></a><a name="IDX-214"></a>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.</p> <p class="para">There are also languages that are <i class="emphasis">interpreted</i> languages. These languages require that the user run a program called an <i class="emphasis">interpreter</i> 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.</p> <p class="para">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.</p> <p class="para">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.</p> <p class="para">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:</p> <ul class="itemizedlist"><li class="first-listitem"> <p class="first-para">Being able to group multiple operations into a single expression</p> </li><li class="listitem"> <p class="first-para">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).</p><a name="345"></a><a name="IDX-215"></a> </li><li class="listitem"> <p class="first-para">Having access to better flow control constructs than just jumps.</p> </li><li class="listitem"> <p class="first-para">Having a compiler to check types of value assignments and other assertions.</p> </li><li class="listitem"> <p class="first-para">Having memory handled automatically.</p> </li><li class="listitem"> <p class="first-para">Being able to work in a language that resembles the problem domain rather than the computer hardware.</p></li></ul> <p class="para">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.</p> <p class="last-para">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.</p><h2 class="first-section-title"><a name="346"></a><a name="ch11lev1sec2"></a>Your First C Program</h2> <p class="first-para">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</p> <div class="informalexample"><pre class="literallayout">#include <stdio.h><br /><br />/* PURPOSE: This program is mean to show a basic */<br />/* C program. All it does is print */<a name="347"></a><a name="IDX-216"></a><br />/* "Hello World!" to the screen and */<br />/* exit. */<br /><br />/* Main Program */<br />int main(int argc, char **argv)<br />{<br />/* Print our string to standard output */<br />puts("Hello World!\n");<br /><br />/* Exit with status 0 */<br />return 0;<br />}<br /></stdio.h></pre></div> <p class="para">As you can see, it's a pretty simple program. To compile it, run the command</p> <div class="informalexample"><pre class="literallayout">gcc -o HelloWorld Hello-World.c<br /></pre></div> <p class="para">To run the program, do</p> <div class="informalexample"><pre class="literallayout">./HelloWorld<br /></pre></div> <p class="para">Let's look at how this program was put together.</p> <p class="para">Comments in C are started with <span class="fixed">/*</span> and ended with <span class="fixed">*/</span>. Comments can span multiple lines, but many people prefer to start and end comments on the same line so they don't get confused.</p> <p class="para"><span class="fixed">#include <stdio.h></stdio.h></span> is the first part of the program. This is a <i class="emphasis">preprocessor directive.</i> C compiling is split into two stages - the preprocessor and the main compiler. This directive tells the preprocessor to look for the file <span class="fixed">stdio.h</span> 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.</p><a name="348"></a><a name="IDX-217"></a> <p class="para">Now, everything in <span class="fixed">stdio.h</span> 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 (<span class="fixed">/usr/include</span> and <span class="fixed">/usr/local/include</span>, usually). If it was in quotes, like <span class="fixed">#include "stdio.h"</span> it would look in the current directory for the file. Anyway, <span class="fixed">stdio.h</span> 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.</p> <p class="para">Then there is the line <span class="fixed">int main (int argc, char **argv)</span>. 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 <span class="fixed">main</span>, it returns an <span class="fixed">int</span> (integer - 4 bytes long on the x86 platform), and has two arguments - an <span class="fixed">int</span> called <span class="fixed">argc</span> and a <span class="fixed">char</span> <span class="fixed">**</span> called <span class="fixed">argv</span>. 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.</p> <p class="para">The <span class="fixed">main</span> function is a special function in the C language - it is the start of all C programs (much like <span class="fixed">_start</span> 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.</p> <p class="para">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 <span class="fixed">puts</span>, 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.</p> <p class="para">Finally our function returns the number <span class="fixed">0</span>. In assembly language, we stored our return value in <span class="fixed">%eax</span>, but in C we just use the <span class="fixed">return</span> command and it takes care <a name="349"></a><a name="IDX-218"></a>of that for us. The return value of the <span class="fixed">main</span> function is what is used as the exit code for the program.</p> <p class="para">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.</p> <p class="last-para">Additional information on the C programming language can be found in <span class="chapterjump">Appendix E</span>.</p><div class="chapter"><a name="ch11"></a> <div class="section"> <h2 class="first-section-title"><a name="350"></a><a name="ch11lev1sec3"></a>Perl</h2> <p class="first-para">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 <span class="fixed">Hello-World.pl</span>:</p> <div class="informalexample"><pre class="literallayout">#!/usr/bin/perl<br /><br />print("Hello world!\n");<br /></pre></div> <p class="para">Since Perl is interpreted, you don't need to compile or link it. Just run in with the following command:</p> <div class="informalexample"><pre class="literallayout">perl Hello-World.pl<br /></pre></div> <p class="para">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 <a name="351"></a><a name="IDX-219"></a>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.</p> <p class="para">The first, optional line is used for UNIX machines to tell which interpreter to use to run the program. The <span class="fixed">#!</span> tells the computer that this is an interpreted program, and the <span class="fixed">/usr/bin/perl</span> tells the computer to use the program <span class="fixed">/usr/bin/perl</span> to interpret the program. However, since we ran the program by typing in <span class="fixed">perl Hello-World.pl</span>, we had already specified that we were using the perl interpreter.</p> <p class="para">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.</p> <p class="last-para">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.</p></div></div><h2 class="first-section-title"><a name="352"></a><a name="ch11lev1sec4"></a>Python</h2> <p class="first-para">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 <span class="fixed">Hello-World.py</span>. The program follows:</p> <div class="informalexample"><pre class="literallayout">#!/usr/bin/python<a name="353"></a><a name="IDX-220"></a><br />print "Hello World"<br /></pre></div> <p class="last-para">You should be able to tell what the different lines of the program do.</p><div class="section"> <h2 class="first-section-title"><a name="354"></a><a name="ch11lev1sec5"></a>Review</h2> <div class="section"> <h3 class="sect3-title"><a name="355"></a><a name="ch11lev2sec1"></a>Know the Concepts</h3> <ul class="itemizedlist"><li class="first-listitem"> <p class="first-para">What is the difference between an intepretted language and a compiled language?</p> </li><li class="listitem"> <p class="first-para">What reasons might cause you to need to learn a new programming language?</p></li></ul></div> <div class="section"> <h3 class="sect3-title"><a name="356"></a><a name="ch11lev2sec2"></a>Use the Concepts</h3> <ul class="itemizedlist"><li class="first-listitem"> <p class="first-para">Learn the basic syntax of a new programming language. Re-code one of the programs in this book in that language.</p> </li><li class="listitem"> <p class="first-para">In the program you wrote in the question above, what specific things were automated in the programming language you chose?</p> </li><li class="listitem"> <p class="first-para">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 <span class="fixed">time</span> command to see which is faster. Which does come out ahead? Why do you think that is?</p> </li><li class="listitem"> <p class="first-para">How does the programming language's input/output methods differ from that of the Linux system calls?</p></li></ul><a name="357"></a><a name="IDX-221"></a></div> <div class="section"> <h3 class="sect3-title"><a name="358"></a><a name="ch11lev2sec3"></a>Going Further</h3> <ul class="itemizedlist"><li class="first-listitem"> <p class="first-para">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?</p> </li><li class="listitem"> <p class="first-para">How do you think high level languages have affected the process of programming?</p> </li><li class="listitem"> <p class="first-para">Why do you think so many languages exist?</p> </li><li class="listitem"> <p class="first-para">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?</p></li></ul><a name="359"></a><a name="IDX-222"></a></div></div></div></div><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8901974503278002812-8236878061672351984?l=programminggroundup.blogspot.com'/></div>Adminhttp://www.blogger.com/profile/13783659974416042562noreply@blogger.com0tag:blogger.com,1999:blog-8901974503278002812.post-73799023947505154482007-01-31T18:40:00.000-08:002008-12-08T14:18:10.193-08:00Chapter 10: Counting like a Computer<a name="291"></a><a name="ch10lev1sec1"></a> <div class="section"> <h3 class="sect3-title"><a name="292"></a><a name="ch10lev2sec1"></a></h3><h2 class="sect2-title"><a name="291"></a><a name="ch10lev1sec1"></a>Counting</h2> <div class="section"> <h3 class="sect3-title"><a name="292"></a><a name="ch10lev2sec1"></a>Counting like a Human</h3></div> <p class="first-para">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.</p> <p class="para">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.</p> <p class="last-para">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 <a name="293"></a><a name="IDX-182"></a>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.</p></div> <div class="section"> <h3 class="sect3-title"><a name="294"></a><a name="ch10lev2sec2"></a>Counting like a Computer</h3> <p class="first-para">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.</p> <p class="para">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:</p> <div class="informalexample"><pre class="literallayout">Table of binary addition<br /><br />+ | 0 | 1<br />--+-----+-----<br />0 | 0 | 0<br />--+-----+-----<br />1 | 1 | 10<br /><br />Table of binary multiplication<a name="295"></a><a name="IDX-183"></a><br />* | 0 | 1<br />--+-----+-----<br />0 | 0 | 0<br />--+-----+-----<br />1 | 0 | 1<br /></pre></div> <p class="para">So, let's add the numbers 10010101 with 1100101:</p> <div class="informalexample"><pre class="literallayout"> 10010101<br />+ 1100101<br />-----------<br />11111010<br /></pre></div> <p class="para">Now, let's multiply them:</p> <div class="informalexample"><pre class="literallayout"> 10010101<br />* 1100101<br />-----------<br /> 10010101<br /> 00000000<br /> 10010101<br />00000000<br />00000000<br />10010101<br />10010101<br />---------------<br />11101011001001<br /><a name="296"></a><a name="IDX-184"></a><br /></pre></div></div> <div class="section"> <h3 class="sect3-title"><a name="297"></a><a name="ch10lev2sec3"></a>Conversions between Binary and Decimal</h3> <p class="first-para">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:</p> <div class="informalexample"><pre class="literallayout"> 1 0 0 1 0 1 0 1<br />| | | | | | | |<br />| | | | | | | Individual units (2^0)<br />| | | | | | 0 groups of 2 (2^1)<br />| | | | | 1 group of 4 (2^2)<br />| | | | 0 groups of 8 (2^3)<br />| | | 1 group of 16 (2^4)<br />| | 0 groups of 32 (2^5)<br />| 0 groups of 64 (2^6)<br />1 group of 128 (2^7)<br /></pre></div> <p class="para">and then we add all of the pieces together, like this:</p> <div class="informalexample"><pre class="literallayout">1*128 + 0*64 + 0*32 + 1*16 + 0*8 + 1*4 + 0*2 + 1*1 =<br />128 + 16 + 4 + 1 =<br />149<br /></pre></div> <p class="para">So 10010101 in binary is 149 in decimal. Let's look at 1100101. It can be written as</p> <div class="informalexample"><pre class="literallayout">1*64 + 1*32 + 0 * 16 + 0*8 + 1*4 + 0*2 + 1*1 =<br />64 + 32 + 4 + 1 =<br />101<br /></pre></div> <p class="para">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</p> <div class="informalexample"><pre class="literallayout">1*8192 + 1*4096 + 1*2048 + 0*1024 + 1*512 + 0*256<a name="298"></a><a name="IDX-185"></a><br /> + 1*128 + 1*64 + 0*32 + 0*16 + 1*8 + 0*4<br /> + 0*2 + 1*1 =<br /><br />8192 + 4096 + 2048 + 512 + 128 + 64 + 8 + 1 =<br /><br />15049<br /></pre></div> <p class="para">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!</p> <p class="para">Now let's look at going from decimal back to binary. In order to do the conversion, you have to <i class="emphasis">divide</i> 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.</p> <p class="para">Previously, we converted to binary 11101011001001 to decimal 15049. Let's do the reverse to make sure that we did it right:</p> <div class="informalexample"><pre class="literallayout">15049 / 2 = 7524 Remaining 1<br />7524 / 2 = 3762 Remaining 0<br />3762 / 2 = 1881 Remaining 0<br />1881 / 2 = 940 Remaining 1<br />940 / 2 = 470 Remaining 0<br />470 / 2 = 235 Remaining 0<br />235 / 2 = 117 Remaining 1<br />117 / 2 = 58 Remaining 1<a name="299"></a><a name="IDX-186"></a><br />58 / 2 = 29 Remaining 0<br />29 / 2 = 14 Remaining 1<br />14 / 2 = 7 Remaining 0<br />7 / 2 = 3 Remaining 1<br />3 / 2 = 1 Remaining 1<br />1 / 2 = 0 Remaining 1<br /></pre></div> <p class="para">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.</p> <p class="para">Each digit in a binary number is called a <i class="emphasis">bit,</i> which stands for <i class="emphasis">binary digit.</i> 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:</p> <div class="informalexample"><pre class="literallayout">11111111 =<br /><br />(1 * 2^7) + (1 * 2^6) + (1 * 2^5) + (1 * 2^4) + (1 * 2^3)<br /> + (1 * 2^2) + (1 * 2^1) + (1 * 2^0) =<br /><br />128 + 64 + 32 + 16 + 8 + 4 + 2 + 1 =<br /><br />255<br /></pre></div> <p class="last-para">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.</p><div class="section"> <h2 class="first-section-title"><a name="300"></a><a name="ch10lev1sec2"></a>Truth, Falsehood, and Binary Numbers</h2><a name="301"></a><a name="IDX-187"></a> <p class="para">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:</p> <div class="informalexample"><pre class="literallayout">Outside Hallway Living Room Bedroom<br />On Off On On<br /></pre></div> <p class="para">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</p> <div class="informalexample"><pre class="literallayout">Outside Hallway Living Room Bedroom<br />1 0 1 1<br /></pre></div> <p class="para">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</p> <div class="informalexample"><pre class="literallayout">1 0 1 1<br /></pre></div> <p class="para">or as</p> <div class="informalexample"><pre class="literallayout">1011<br /></pre></div> <p class="para">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 <a name="302"></a><a name="IDX-188"></a>come up with. They just sometimes have to be creative when figuring out the best representation.</p> <p class="para">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</p> <ul class="itemizedlist"><li class="first-listitem"> <p class="first-para">AND</p> </li><li class="listitem"> <p class="first-para">OR</p> </li><li class="listitem"> <p class="first-para">NOT</p> </li><li class="listitem"> <p class="first-para">XOR</p></li></ul> <p class="para">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.</p> <p class="para">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.</p> <p class="para">NOT only takes one bit and returns its opposite. NOT 1 is 0 and NOT 0 is 1.</p> <p class="para">Finally, XOR is like OR, except it returns 0 if both bits are 1.</p> <p class="para">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:</p> <div class="informalexample"><pre class="literallayout">10100010101010010101101100101010 AND<br />10001000010101010101010101111010<br />--------------------------------<br />10000000000000010101000100101010<br /><a name="303"></a><a name="IDX-189"></a><br /></pre></div> <p class="para">You'll see that the resulting set of bits only has a one where <i class="emphasis">both</i> numbers had a one, and in every other position it has a zero. Let's look at what an OR looks like:</p> <div class="informalexample"><pre class="literallayout">10100010101010010101101100101010 OR<br />10001000010101010101010101111010<br />--------------------------------<br />10101010111111010101111101111010<br /></pre></div> <p class="para">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:</p> <div class="informalexample"><pre class="literallayout">NOT 10100010101010010101101100101010<br />------------------------------------<br />01011101010101101010010011010101<br /></pre></div> <p class="para">This just reverses each digit. Finally, we have XOR, which is like an OR, except if <i class="emphasis">both</i> digits are 1, it returns 0.</p> <div class="informalexample"><pre class="literallayout">10100010101010010101101100101010 XOR<br />10001000010101010101010101111010<br />--------------------------------<br />00101010111111000000111001010000<br /></pre></div> <p class="para">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:</p> <div class="informalexample"><pre class="literallayout">10100010101010010101101100101010 XOR<br />10100010101010010101101100101010<br />--------------------------------<br />00000000000000000000000000000000<br /></pre></div> <p class="para">These operations are useful for two reasons:</p> <ul class="itemizedlist"><li class="first-listitem"> <p class="first-para">The computer can do them extremely fast</p><a name="304"></a><a name="IDX-190"></a> </li><li class="listitem"> <p class="first-para">You can use them to compare many truth values at the same time</p></li></ul> <p class="para">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</p> <div class="informalexample"><pre class="literallayout"> movl $0, %eax<br /></pre></div> <p class="para">is often replaced by</p> <div class="informalexample"><pre class="literallayout"> xorl %eax, %eax<br /></pre></div> <p class="para">We'll discuss speed more in <span class="chapterjump">Chapter 12</span>, 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:</p> <div class="informalexample"><pre class="literallayout">Food: yes<br />Heavy Metal Music: yes<br />Wearing Dressy Clothes: no<br />Football: yes<br /></pre></div> <p class="para">Now, let's look at what my Dad likes:</p> <div class="informalexample"><pre class="literallayout">Food: yes<br />Heavy Metal Music: no<br />Wearing Dressy Clothes: yes<br />Football: yes<br /></pre></div> <p class="para">Now, let's use a 1 to say yes we like something, and a 0 to say no we don't. Now we have:</p><a name="305"></a><a name="IDX-191"></a> <div class="informalexample"><pre class="literallayout">Me<br />Food: 1<br />Heavy Metal Music: 1<br />Wearing Dressy Clothes: 0<br />Football: 1<br /><br />Dad<br />Food: 1<br />Heavy Metal Music: 0<br />Wearing Dressy Clothes: 1<br />Football: 1<br /></pre></div> <p class="para">Now, if we just memorize which position each of these are in, we have</p> <div class="informalexample"><pre class="literallayout">Me<br />1101<br /><br />Dad<br />1011<br /></pre></div> <p class="para">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</p> <div class="informalexample"><pre class="literallayout">1101 AND<br />1011<br />--------<br />1001<br /></pre></div> <p class="para">Which translates to</p> <div class="informalexample"><pre class="literallayout">Things we both like<br />Food: yes<br />Heavy Metal Music: no<br />Wearing Dressy Clothes: no<br />Football: yes<br /><a name="306"></a><a name="IDX-192"></a><br /></pre></div> <p class="para">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</p> <div class="informalexample"><pre class="literallayout">1101 XOR<br />1011<br />--------<br />0110<br /></pre></div> <p class="para">And I'll let you translate that back out.</p> <p class="para">The previous operations: AND, OR, NOT, and XOR are called <i class="emphasis">boolean operators</i> 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.</p> <p class="para">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,</p> <div class="informalexample"><pre class="literallayout">Shift left 10010111 = 00101110<br />Rotate left 10010111 = 00101111<br /></pre></div> <p class="para">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 <i class="emphasis">shift</i> 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:</p><a name="307"></a><a name="IDX-193"></a> <div class="informalexample"><pre class="literallayout">00000000000000000000000000001011<br /></pre></div> <p class="para">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 <i class="emphasis">masking.</i> 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:</p> <div class="informalexample"><pre class="literallayout">00000000000000000000000000000101<br /></pre></div> <p class="para">and then, we just want to look at that digit, so we mask it by ANDing it with 00000000000000000000000000000001.</p> <div class="informalexample"><pre class="literallayout">00000000000000000000000000000101 AND<br />00000000000000000000000000000001<br />-----------------------------------<br />00000000000000000000000000000001<br /></pre></div> <p class="para">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:</p> <div class="informalexample"><pre class="literallayout"> #NOTE - assume that the register %ebx holds<br /># my Dad's preferences<br /><br />movl %ebx, %eax #This copies the information into %eax so<br /> #we don't lose the original data<br /><br />shrl $1, %eax #This is the shift operator. It stands<br /> #for Shift Right Long. This first number<br /> #is the number of positions to shift,<a name="308"></a><a name="IDX-194"></a><br /> #and the second is the register to shift<br /><br />#This does the masking<br />andl $0b00000000000000000000000000000001, %eax<br /><br />#Check to see if the result is 1 or 0<br />cmpl $0b00000000000000000000000000000001, %eax<br /><br />je yes_he_likes_dressy_clothes<br /><br />jmp no_he_doesnt_like_dressy_clothes<br /></pre></div> <p class="para">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.</p> <p class="para">When a number represents a set of options for a function or system call, the individual true/false elements are called <i class="emphasis">flags.</i> Many system calls have numerous options that are all set in the same register using a mechanism like we've described. The <span class="fixed">open</span> 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:</p> <p class="para"><span class="fixed">O_WRONLY</span> </p> <ul class="simple-list"><li class="first-listitem"> <p class="first-para">This flag is <span class="fixed">0b00000000000000000000000000000001</span> in binary, or <span class="fixed">01</span> in octal (or any number system for that matter). This says to open the file in write-only mode.</p></li></ul> <p class="para"><span class="fixed">O_RDWR</span> </p> <ul class="simple-list"><li class="first-listitem"> <p class="first-para">This flag is <span class="fixed">0b00000000000000000000000000000010</span> in binary, or <span class="fixed">02</span> in octal. This says to open the file for both reading and writing.</p></li></ul><a name="309"></a><a name="IDX-195"></a> <p class="para"><span class="fixed">O_CREAT</span> </p> <ul class="simple-list"><li class="first-listitem"> <p class="first-para">This flag is <span class="fixed">0b00000000000000000000000001000000</span> in binary, or <span class="fixed">0100</span> in octal. It means to create the file if it doesn't already exist.</p></li></ul> <p class="para"><span class="fixed">O_TRUNC</span> </p> <ul class="simple-list"><li class="first-listitem"> <p class="first-para">This flag is <span class="fixed">0b00000000000000000000001000000000</span> in binary, or <span class="fixed">01000</span> in octal. It means to erase the contents of the file if the file already exists.</p></li></ul> <p class="para"><span class="fixed">O_APPEND</span> </p> <ul class="simple-list"><li class="first-listitem"> <p class="first-para">This flag is <span class="fixed">0b00000000000000000000010000000000</span> in binary, or <span class="fixed">02000</span> in octal. It means to start writing at the end of the file rather than at the beginning.</p></li></ul> <p class="para">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 <span class="fixed">O_WRONLY</span> (01) and <span class="fixed">O_CREAT</span> (0100). OR'd together, I would have 0101.</p> <p class="para">Note that if you don't set either <span class="fixed">O_WRONLY</span> or <span class="fixed">O_RDWR</span>, then the file is automatically opened in read-only mode (<span class="fixed">O_RDONLY</span>, except that it isn't really a flag since it's zero).</p> <p class="last-para">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.</p><h2 class="first-section-title"><a name="310"></a><a name="ch10lev1sec3"></a>The Program Status Register</h2> <p class="first-para">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 <i class="emphasis">program status register.</i> This register holds a lot of information about what happens in a computation. For example, have you ever wondered what would happen if you <a name="311"></a><a name="IDX-196"></a>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 (<span class="fixed">cmpl</span>) instruction, the result is stored in this register. The conditional jump instructions (<span class="fixed">jge</span>, <span class="fixed">jne</span>, etc) use these results to tell whether or not they should jump. <span class="fixed">jmp</span>, the unconditional jump, doesn't care what is in the status register, since it is unconditional.</p> <p class="para">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.</p> <p class="last-para">Additional program status register flags are examined in <span class="chapterjump">Appendix B</span>.</p><div class="section"> <h2 class="first-section-title"><a name="312"></a><a name="ch10lev1sec4"></a>Other Numbering Systems</h2> <p class="first-para">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.</p> <div class="section"> <h3 class="sect3-title"><a name="313"></a><a name="ch10lev2sec4"></a>Floating-Point Numbers</h3> <p class="first-para">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, <a name="314"></a><a name="IDX-197"></a>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).</p> <p class="para">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 <i class="emphasis">exponent</i> and the <i class="emphasis">mantissa.</i> 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 <i class="emphasis">floating point</i> representation, because the position of the significant digits with respect to the decimal point can vary based on the exponent.</p> <p class="para">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.</p> <p class="para">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.</p><a name="315"></a><a name="IDX-198"></a></div> <div class="section"> <h3 class="sect3-title"><a name="316"></a><a name="ch10lev2sec5"></a>Negative Numbers</h3> <p class="first-para">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 <span class="fixed">00000000000000000000000000000001</span> would represent the number 1, and <span class="fixed">10000000000000000000000000000001</span> 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?".</p> <p class="para">These problems were overcome by using a representation of negative numbers called <i class="emphasis">two's complement</i> representation. To get the negative representation of a number in two's complement form, you must perform the following steps:</p> <ol class="orderedlist"><li class="first-listitem"> <p class="first-para">Perform a NOT operation on the number</p> </li><li class="listitem"> <p class="first-para">Add one to the resulting number</p></li></ol> <p class="para">So, to get the negative of <span class="fixed">00000000000000000000000000000001</span>, you would first do a NOT operation, which gives <span class="fixed">1111111111111111111111111111110</span>, and then add one, giving <span class="fixed">11111111111111111111111111111111</span>. To get negative two, first take <span class="fixed">00000000000000000000000000000010</span>. The NOT of that number is <span class="fixed">11111111111111111111111111111101</span>. Adding one gives <span class="fixed">11111111111111111111111111111110</span>. 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 <span class="fixed">1</span> 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 <a name="317"></a><a name="IDX-199"></a>byte can normally have values up to 255. A signed byte, however, can store values from -128 to 127.</p> <p class="para">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, <span class="fixed">1101</span>. If we were to extend this into an eight-bit register, we could not represent it as <span class="fixed">00001101</span> 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 <i class="emphasis">sign extension.</i> 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 <span class="fixed">11111101</span>.</p> <p class="last-para">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 <span class="chapterjump">Appendix B</span>. For example, the x86 processor has both a sign-preserving shift-right, <span class="fixed">sarl</span>, and a shift-right which does not preserve the sign bit, <span class="fixed">shrl</span>.</p><div class="section"> <h2 class="first-section-title"><a name="318"></a><a name="ch10lev1sec5"></a>Octal and Hexadecimal Numbers</h2> <p class="first-para">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 <a name="319"></a><a name="IDX-200"></a>is 111.</p> <p class="para">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, <span class="fixed">0751</span> 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.</p> <p class="para">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, <i class="emphasis">be careful not to put any leading zeroes in front of decimal numbers, or they will be interepreted as octal numbers</i>!</p> <p class="para">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 <span class="fixed">a</span> through <span class="fixed">f</span> to represent them. For example, the letter <span class="fixed">a</span> represents 10, the letter <span class="fixed">b</span> 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 <span class="fixed">f</span>, 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</p> <div class="informalexample"><pre class="literallayout"> movl $0xFFFFFFFF, %eax<br /><a name="320"></a><a name="IDX-201"></a><br /></pre></div> <p class="para">Which is considerably easier and less error-prone than writing</p> <div class="informalexample"><pre class="literallayout">movl $0b11111111111111111111111111111111, %eax<br /></pre></div> <p class="para">Note also that hexadecimal numbers are prefixed with <span class="fixed">0x</span>. So, when we do</p> <div class="informalexample"><pre class="literallayout"> int $0x80<br /></pre></div> <p class="para">We are calling interrupt number 128 (8 groups of 16), or interrupt number <span class="fixed">0b00000000000000000000000010000000</span>.</p> <p class="last-para">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.</p><div class="chapter"><a name="ch10"></a> <div class="section"> <h2 class="first-section-title"><a name="321"></a><a name="ch10lev1sec6"></a>Order of Bytes in a Word</h2> <p class="first-para">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. <sup>[<a href="http://www2.blogger.com/post-edit.g?blogID=8901974503278002812&postID=7379902394750515448#ftn.N15" name="N15">1</a>]</sup> What most people expect is that if they have a word in a register, say <span class="fixed">0x5d 23 ef ee</span> (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 <span class="fixed">0xee ef 23 5d</span> 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.</p> <p class="para">Not all processors behave this way. The x86 processor is a <i class="emphasis">little-endian</i> processor, which means that it stores the "little end", or least-significant byte of its words first.</p><a name="322"></a><a name="IDX-202"></a> <div class="figure"><a name="323"></a><span class="figuremediaobject"><a href="http://www2.blogger.com/images/fig210%5F01%5F0%2Ejpg" target="_parent" name="IMG_4"></a></span><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_pYXuXAWhUJk/RcF1KZB51tI/AAAAAAAAAB0/zSMvQxrGtJA/s1600-h/Fig04.jpg"><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" /></a><a href="http://www2.blogger.com/images/fig210%5F01%5F0%2Ejpg" target="_parent" name="IMG_4"></a><span class="figuremediaobject"><a href="http://www2.blogger.com/images/fig210%5F01%5F0%2Ejpg" target="_parent" name="IMG_4"></a></span><br /><span class="figure-title">Register-to-memory transfers on little-endian systems</span> </div> <p class="para">Other processors are <i class="emphasis">big-endian</i> 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.</p><a name="324"></a><a name="IDX-203"></a> <div class="figure"><a name="325"></a><span class="figuremediaobject"><a href="http://www2.blogger.com/images/fig211%5F01%5F0%2Ejpg" target="_parent" name="IMG_5"></a></span><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_pYXuXAWhUJk/RcF1a5B51uI/AAAAAAAAAB8/LltsaaZhosk/s1600-h/Fig05.jpg"><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" /></a><a href="http://www2.blogger.com/images/fig211%5F01%5F0%2Ejpg" target="_parent" name="IMG_5"></a><span class="figuremediaobject"><a href="http://www2.blogger.com/images/fig211%5F01%5F0%2Ejpg" target="_parent" name="IMG_5"></a></span><br /><span class="figure-title">Register-to-memory transfers on big-endian systems</span> </div> <p class="para">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:</p> <ul class="itemizedlist"><li class="first-listitem"> <p class="first-para">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 <span class="fixed">%al</span> and/or shifting of the register), this will be in a different order than they appear in memory.</p><a name="326"></a><a name="IDX-204"></a> </li><li class="listitem"> <p class="first-para">If you read or write files written for different architectures, you may have to account for whatever order they write their bytes in.</p> </li><li class="listitem"> <p class="first-para">If you read or write to network sockets, you may have to account for a different byte order in the protocol.</p></li></ul> <p class="last-para">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 <a class="url" href="http://www.rdrop.com/%7Ecary/html/endian_faq.html" target="_top">http://www.rdrop.com/~cary/html/endian_faq.html</a>, especially the article "On Holy Wars and a Plea for Peace" by Daniel Cohen.</p></div> <div class="footnotes"> <div class="footnote"> <p><sup>[<a href="http://www2.blogger.com/post-edit.g?blogID=8901974503278002812&postID=7379902394750515448#N15" name="ftn.N15">1</a>]</sup><i class="emphasis">Significance</i> 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.</p><h2 class="first-section-title"><a name="327"></a><a name="ch10lev1sec7"></a>Converting Numbers for Display</h2> <p class="first-para">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.</p> <p class="para">The function will be called <span class="fixed">integer2string</span>, 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).</p> <p class="para">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:</p> <ul class="itemizedlist"><li class="first-listitem"> <p class="first-para">Divide the number by ten</p> </li><li class="listitem"> <p class="first-para">The remainder is the current digit. Convert it to a character and store it.</p> </li><li class="listitem"> <p class="first-para">We are finished if the quotient is zero.</p> </li><li class="listitem"> <p class="first-para">Otherwise, take the quotient and the next location in the buffer and repeat the process.</p></li></ul><a name="328"></a><a name="IDX-205"></a> <p class="para">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.</p> <p class="para">The code for the function should be put in a file called <span class="fixed">integer-to-string.s</span> and should be entered as follows:</p> <div class="informalexample"><pre class="literallayout">#PURPOSE: Convert an integer number to a decimal string<br /># for display<br />#<br />#INPUT: A buffer large enough to hold the largest<br /># possible number<br /># An integer to convert<br />#<br />#OUTPUT: The buffer will be overwritten with the<br /># decimal string<br />#<br />#Variables:<br />#<br /># %ecx will hold the count of characters processed<br /># %eax will hold the current value<br /># %edi will hold the base (10)<br />#<br />.equ ST_VALUE, 8<br />.equ ST_BUFFER, 12<br /><br />.globl integer2string<br />.type integer2string, @function<br />integer2string:<br />#Normal function beginning<br />pushl %ebp<br />movl %esp, %ebp<a name="329"></a><a name="IDX-206"></a><br />#Current character count<br />movl $0, %ecx<br /><br />#Move the value into position<br />movl ST_VALUE(%ebp), %eax<br /><br />#When we divide by 10, the 10<br />#must be in a register or memory location<br />movl $10, %edi<br /><br />conversion_loop:<br />#Division is actually performed on the<br />#combined %edx:%eax register, so first<br />#clear out %edx<br />movl $0, %edx<br /><br />#Divide %edx:%eax (which are implied) by 10.<br />#Store the quotient in %eax and the remainder<br />#in %edx (both of which are implied).<br />divl %edi<br /><br />#Quotient is in the right place. %edx has<br />#the remainder, which now needs to be converted<br />#into a number. So, %edx has a number that is<br />#0 through 9. You could also interpret this as<br />#an index on the ASCII table starting from the<br />#character '0'. The ascii code for '0' plus zero<br />#is still the ascii code for '0'. The ascii code<br />#for '0' plus 1 is the ascii code for the<br />#character '1'. Therefore, the following<br />#instruction will give us the character for the<br />#number stored in %edx<br />addl $'0', %edx<br /><br />#Now we will take this value and push it on the<a name="330"></a><a name="IDX-207"></a><br />#stack. This way, when we are done, we can just<br />#pop off the characters one-by-one and they will<br />#be in the right order. Note that we are pushing<br />#the whole register, but we only need the byte<br />#in %dl (the last byte of the %edx register) for<br />#the character.<br />pushl %edx<br /><br />#Increment the digit count<br />incl %ecx<br /><br />#Check to see if %eax is zero yet, go to next<br />#step if so.<br />cmpl $0, %eax<br />je end_conversion_loop<br /><br />#%eax already has its new value.<br /><br />jmp conversion_loop<br /><br />end_conversion_loop:<br />#The string is now on the stack, if we pop it<br />#off a character at a time we can copy it into<br />#the buffer and be done.<br /><br />#Get the pointer to the buffer in %edx<br />movl ST_BUFFER(%ebp), %edx<br /><br />copy_reversing_loop:<br />#We pushed a whole register, but we only need<br />#the last byte. So we are going to pop off to<br />#the entire %eax register, but then only move the<br />#small part (%al) into the character string.<br />popl %eax<br />movb %al, (%edx)<a name="331"></a><a name="IDX-208"></a><br />#Decreasing %ecx so we know when we are finished<br />decl %ecx<br />#Increasing %edx so that it will be pointing to<br />#the next byte<br />incl %edx<br /><br />#Check to see if we are finished<br />cmpl $0, %ecx<br />#If so, jump to the end of the function<br />je end_copy_reversing_loop<br />#Otherwise, repeat the loop<br />jmp copy_reversing_loop<br /><br />end_copy_reversing_loop:<br />#Done copying. Now write a null byte and return<br />movb $0, (%edx)<br /><br />movl %ebp, %esp<br />popl %ebp<br />ret<br /></pre></div> <p class="para">To show this used in a full program, use the following code, along with the <span class="fixed">count_chars</span> and <span class="fixed">write_newline</span> functions written about in previous chapters. The code should be in a file called <span class="fixed">conversion-program.s.</span> </p> <div class="informalexample"><pre class="literallayout"> .include "linux.s"<br /><br />.section .data<br /><br />#This is where it will be stored<br />tmp_buffer:<br />.ascii "\0\0\0\0\0\0\0\0\0\0\0"<a name="332"></a><a name="IDX-209"></a><br />.section .text<br /><br />.globl _start<br />_start:<br />movl %esp, %ebp<br /><br />#Storage for the result<br />pushl $tmp_buffer<br />#Number to convert<br />pushl $824<br />call integer2string<br />addl $8, %esp<br /><br />#Get the character count for our system call<br />pushl $tmp_buffer<br />call count_chars<br />addl $4, %esp<br /><br />#The count goes in %edx for SYS_WRITE<br />movl %eax, %edx<br /><br />#Make the system call<br />movl $SYS_ WRITE, %eax<br />movl $STDOUT, %ebx<br />movl $tmp_buffer, %ecx<br /><br />int $LINUX_SYSCALL<br /><br />#Write a carriage return<br />pushl $STDOUT<br />call write_newline<br /><br />#Exit<br />movl $SYS_EXIT, %eax<a name="333"></a><a name="IDX-210"></a><br />movl $0, %ebx<br />int $LINUX_SYSCALL<br /></pre></div> <p class="para">To build the program, issue the following commands:</p> <div class="informalexample"><pre class="literallayout">as integer-to-string.s -o integer-to-number.o<br />as count-chars.s -o count-chars.o<br />as write-newline.s -o write-newline.o<br />as conversion-program.s -o conversion-program.o<br />ld integer-to-number.o count-chars.o write-newline.o conversion-<br />program.o -o conversion-program<br /></pre></div> <p class="last-para">To run just type <span class="fixed">./conversion-program</span> and the output should say <span class="fixed">824.</span></p><h2 class="first-section-title"><a name="334"></a><a name="ch10lev1sec8"></a>Review</h2> <div class="section"> <h3 class="sect3-title"><a name="335"></a><a name="ch10lev2sec6"></a>Know the Concepts</h3> <ul class="itemizedlist"><li class="first-listitem"> <p class="first-para">Convert the decimal number 5,294 to binary.</p> </li><li class="listitem"> <p class="first-para">What number does 0x0234aeff represent? Specify in binary, octal, and decimal.</p> </li><li class="listitem"> <p class="first-para">Add the binary numbers 10111001 and 101011.</p> </li><li class="listitem"> <p class="first-para">Multiply the binary numbers 1100 1010110.</p> </li><li class="listitem"> <p class="first-para">Convert the results of the previous two problems into decimal.</p> </li><li class="listitem"> <p class="first-para">Describe how AND, OR, NOT, and XOR work.</p> </li><li class="listitem"> <p class="first-para">What is masking for?</p> </li><li class="listitem"> <p class="first-para">What number would you use for the flags of the <span class="fixed">open</span> system call if you wanted to open the file for writing, and create the file if it doesn't exist?</p><a name="336"></a><a name="IDX-211"></a> </li><li class="listitem"> <p class="first-para">How would you represent -55 in a thirty-two bit register?</p> </li><li class="listitem"> <p class="first-para">Sign-extend the previous quantity into a 64-bit register.</p> </li><li class="listitem"> <p class="first-para">Describe the difference between little-endian and big-endian storage of words in memory.</p></li></ul></div> <div class="section"> <h3 class="sect3-title"><a name="337"></a><a name="ch10lev2sec7"></a>Use the Concepts</h3> <ul class="itemizedlist"><li class="first-listitem"> <p class="first-para">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.</p> </li><li class="listitem"> <p class="first-para">Modify the <span class="fixed">integer2string</span> code to return results in octal rather than decimal.</p> </li><li class="listitem"> <p class="first-para">Modify the <span class="fixed">integer2string</span> code so that the conversion base is a parameter rather than hardcoded.</p> </li><li class="listitem"> <p class="first-para">Write a function called <span class="fixed">is_negative</span> that takes a single integer as a parameter and returns 1 if the parameter is negative, and 0 if the parameter is positive.</p></li></ul></div> <div class="section"> <h3 class="sect3-title"><a name="338"></a><a name="ch10lev2sec8"></a>Going Further</h3> <ul class="itemizedlist"><li class="first-listitem"> <p class="first-para">Modify the <span class="fixed">integer2string</span> code so that the conversion base can be greater than 10 (this requires you to use letters for numbers past 9).</p> </li><li class="listitem"> <p class="first-para">Create a function that does the reverse of <span class="fixed">integer2string</span> called <span class="fixed">number2integer</span> which takes a character string and converts it to a register-sized integer. Test it by running that integer back through the <span class="fixed">integer2string</span> function and displaying the results.</p> </li><li class="listitem"> <p class="first-para">Write a program that stores likes and dislikes into a single machine word, and then compares two sets of likes and dislikes for commonalities.</p><a name="339"></a><a name="IDX-212"></a> </li><li class="listitem"> <p class="first-para">Write a program that reads a string of characters from STDIN and converts them to a number.</p></li></ul></div></div></div></div></div></div></div></div></div><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8901974503278002812-7379902394750515448?l=programminggroundup.blogspot.com'/></div>Adminhttp://www.blogger.com/profile/13783659974416042562noreply@blogger.com0tag:blogger.com,1999:blog-8901974503278002812.post-32849684770634165732007-01-31T18:26:00.000-08:002008-12-08T14:18:10.266-08:00Chapter 9: Intermediate Memory Topics<div class="section"> <h2 class="sect2-title"><a name="239"></a><a name="ch09lev1sec1"></a>How a Computer Views Memory</h2> <p class="first-para">Let's review how memory within a computer works. You may also want to re-read <span class="chapterjump">Chapter 2</span>.</p> <p class="para">A computer looks at memory as a long sequence of numbered storage locations. A sequence of <i class="emphasis">millions</i> 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.</p> <p class="para">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</p> <div class="informalexample"><pre class="literallayout"> movl data_items(,%edi,4), %ebx<br /></pre></div> <p class="para">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 <span class="fixed">data_items.</span> 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.</p> <p class="para">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:</p><a name="240"></a><a name="IDX-148"></a> <p class="para">Byte</p> <ul class="simple-list"><li class="first-listitem"> <p class="first-para">This is the size of a storage location. On x86 processors, a byte can hold numbers between 0 and 255.</p></li></ul> <p class="para">Word</p> <ul class="simple-list"><li class="first-listitem"> <p class="first-para">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.</p></li></ul> <p class="para">Address</p> <ul class="simple-list"><li class="first-listitem"> <p class="first-para">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. <sup>[<a href="http://www2.blogger.com/post-edit.g?blogID=8901974503278002812&postID=3284968477063416573#ftn.N73" name="N73">1</a>]</sup> 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.</p> </li><li class="listitem"> <p class="first-para">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:</p> <div class="informalexample"><pre class="literallayout"> .section .data<br />my_data:<br />.long 2, 3, 4<br /></pre></div> </li><li class="listitem"> <p class="first-para">Now, any time in the program that <span class="fixed">my_data</span> is used, it will be replaced by the address of the first value of the <span class="fixed">.long</span> directive.</p></li></ul> <p class="para">Pointer</p> <ul class="simple-list"><li class="first-listitem"> <p class="first-para">A pointer is a register or memory word whose value is an address. In our programs we use <span class="fixed">%ebp</span> as a pointer to the current stack frame. All base <a name="241"></a><a name="IDX-149"></a>pointer addressing involves pointers. Programming uses a lot of pointers, so it's an important concept to grasp.</p></li></ul></div> <div class="footnotes"> <div class="footnote"> <p><sup>[<a href="http://www2.blogger.com/post-edit.g?blogID=8901974503278002812&postID=3284968477063416573#N73" name="ftn.N73">1</a>]</sup>You actually never use addresses this low, but it works for discussion.</p><div class="section"> <h2 class="first-section-title"><a name="242"></a><a name="ch09lev1sec2"></a>The Memory Layout of a Linux Program</h2> <p class="first-para">When you program is loaded into memory, each <span class="fixed">.section</span> 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.</p> <p class="para">The actual instructions (the <span class="fixed">.text</span> section) are loaded at the address 0x08048000 (numbers starting with 0x are in hexadecimal, which will be discussed in <span class="chapterjump">Chapter 10</span>). <sup>[<a href="http://www2.blogger.com/post-edit.g?blogID=8901974503278002812&postID=3284968477063416573#ftn.N29" name="N29">2</a>]</sup> The <span class="fixed">.data</span> section is loaded immediately after that, followed by the <span class="fixed">.bss</span> section.</p> <p class="para">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 <span class="chapterjump">Chapter 4</span>), 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 <span class="fixed">as</span>, for example, we give it several arguments - <span class="fixed">as</span>, <span class="fixed">sourcefile.s</span>,<span class="fixed">-o</span>, and <span class="fixed">objectfile. o.</span> After these, we have the number of arguments that were used. When the program begins, this is where the stack pointer, <span class="fixed">%esp</span>, is pointing. Further pushes on the stack move <span class="fixed">%esp</span> down in memory. For example, the instruction</p> <div class="informalexample"><pre class="literallayout"> pushl %eax<br /></pre></div> <p class="para">is equivalent to</p><a name="243"></a><a name="IDX-150"></a> <div class="informalexample"><pre class="literallayout"> movl %eax, (%esp)<br />subl $4, %esp<br /></pre></div> <p class="para">Likewise, the instruction</p> <div class="informalexample"><pre class="literallayout"> popl %eax<br /></pre></div> <p class="para">is the same as</p> <div class="informalexample"><pre class="literallayout"> movl (%esp), %eax<br />addl $4, %esp<br /></pre></div> <p class="para">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. <sup>[<a href="http://www2.blogger.com/post-edit.g?blogID=8901974503278002812&postID=3284968477063416573#ftn.N109" name="N109">3</a>]</sup> 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 <i class="emphasis">system break</i> (also called the <i class="emphasis">current break</i> or just the <i class="emphasis">break</i>).</p><a name="244"></a><a name="IDX-151"></a> <div class="figure"><a name="245"></a><span class="figuremediaobject"><a href="http://www2.blogger.com/images/fig159%5F01%5F0%2Ejpg" target="_parent" name="IMG_3"></a></span><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_pYXuXAWhUJk/RcF0u5B51sI/AAAAAAAAABo/mZeE9f08GIA/s1600-h/Fig03.jpg"><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" /></a><a href="http://www2.blogger.com/images/fig159%5F01%5F0%2Ejpg" target="_parent" name="IMG_3"></a><span class="figuremediaobject"><a href="http://www2.blogger.com/images/fig159%5F01%5F0%2Ejpg" target="_parent" name="IMG_3"></a></span><br /><span class="figure-title">Memory Layout of a Linux Program at Startup</span> </div></div> <div class="footnotes"> <div class="footnote"> <p><sup>[<a href="http://www2.blogger.com/post-edit.g?blogID=8901974503278002812&postID=3284968477063416573#N29" name="ftn.N29">2</a>]</sup>Addresses mentioned in this chapter are not set in stone and may vary based on kernel version.</p></div> <div class="footnote"> <p><sup>[<a href="http://www2.blogger.com/post-edit.g?blogID=8901974503278002812&postID=3284968477063416573#N109" name="ftn.N109">3</a>]</sup>The stack can access it as it grows downward, and you can access the stack regions through <span class="fixed">%esp.</span> However, your program's data section doesn't grow that way. The way to grow that will be explained shortly.</p><div class="chapter"><a name="ch09"></a> <div class="section"> <h2 class="first-section-title"><a name="246"></a><a name="ch09lev1sec3"></a>Every Memory Address is a Lie</h2> <p class="first-para">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.</p> <p class="para">You may have wondered, since every program gets loaded into the same place in <a name="247"></a><a name="IDX-152"></a>memory, don't they step on each other, or overwrite each other? It would seem so. However, as a program writer, you only access <i class="emphasis">virtual memory.</i> </p> <p class="para"><i class="emphasis">Physical memory</i> 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 <i class="emphasis">physical memory address,</i> we are talking about where exactly on these chips a piece of memory is located. Virtual memory is the way <i class="emphasis">your program</i> 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.</p> <p class="para">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 <i class="emphasis">mapping.</i> </p> <p class="para">Earlier we talked about the inaccessible memory between the <span class="fixed">.bss</span> 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.</p> <p class="para">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, <a name="248"></a><a name="IDX-153"></a>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.</p> <p class="para">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. <sup>[<a href="http://www2.blogger.com/post-edit.g?blogID=8901974503278002812&postID=3284968477063416573#ftn.N53" name="N53">4</a>]</sup> </p> <p class="para">Here is an overview of the way memory accesses are handled under Linux:</p> <ul class="itemizedlist"><li class="first-listitem"> <p class="first-para">The program tries to load memory from a virtual address.</p> </li><li class="listitem"> <p class="first-para">The processor, using tables supplied by Linux, transforms the virtual memory address into a physical memory address on the fly.</p><a name="249"></a><a name="IDX-154"></a> </li><li class="listitem"> <p class="first-para">If the processor does not have a physical address listed for the memory address, it sends a request to Linux to load it.</p> </li><li class="listitem"> <p class="first-para">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.</p> </li><li class="listitem"> <p class="first-para">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.</p> </li><li class="listitem"> <p class="first-para">Linux then moves the data into a free physical memory address.</p> </li><li class="listitem"> <p class="first-para">Linux updates the processor's virtual-to-physical memory mapping tables to reflect the changes.</p> </li><li class="listitem"> <p class="first-para">Linux restores control to the program, causing it to re-issue the instruction which caused this process to happen.</p> </li><li class="listitem"> <p class="first-para">The processor can now handle the instruction using the newly-loaded memory and translation tables.</p></li></ul> <p class="para">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.</p> <p class="para">Now, in order to make the process more efficient, memory is separated out into groups called <i class="emphasis">pages.</i> 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.</p> <p class="para">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 <a name="250"></a><a name="IDX-155"></a>and off of disk than they do actually processing it. This leads to a condition called <i class="emphasis">swap death</i> 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.</p> <ul class="simple-list"><li class="first-listitem"> <p class="para"><b>Resident Set Size:</b> 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 <span class="fixed">top</span>. The resident set size is listed under the column labelled "RSS".</p></li></ul></div> <div class="footnotes"> <div class="footnote"> <p><sup>[<a href="http://www2.blogger.com/post-edit.g?blogID=8901974503278002812&postID=3284968477063416573#N53" name="ftn.N53">4</a>]</sup>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.</p><div class="chapter"><a name="ch09"></a> <div class="section"> <h2 class="first-section-title"><a name="251"></a><a name="ch09lev1sec4"></a>Getting More Memory</h2> <p class="first-para">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 <span class="fixed">.data</span> or <span class="fixed">.bss</span> 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.</p> <p class="para">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 <span class="fixed">brk</span> system call. The <span class="fixed">brk</span> system call is call number <a name="252"></a><a name="IDX-156"></a>45 (which will be in <span class="fixed">%eax</span>). <span class="fixed">%ebx</span> should be loaded with the requested breakpoint. Then you call <span class="fixed">int $0x80</span> to signal Linux to do its work. After mapping in your memory, Linux will return the new break point in <span class="fixed">%eax.</span> 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 <span class="fixed">%eax.</span> Also, if you call <span class="fixed">brk</span> with a zero in <span class="fixed">%ebx</span>, it will simply return the last usable memory address.</p> <p class="para">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 <i class="emphasis">memory manager.</i> </p> <p class="para">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 - <span class="fixed">allocate</span> and <span class="fixed">deallocate</span>. <sup>[<a href="http://www2.blogger.com/post-edit.g?blogID=8901974503278002812&postID=3284968477063416573#ftn.N80" name="N80">5</a>]</sup> Whenever you need a certain amount of memory, you can simply tell <span class="fixed">allocate</span> how much you need, and it will give you back an address to the memory. When you're done with it, you tell <span class="fixed">deallocate</span> that you are through with it. <span class="fixed">allocate</span> will then be able to reuse the memory. This pattern of memory management is called <i class="emphasis">dynamic memory allocation.</i> 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 <i class="emphasis">the heap.</i> </p> <p class="last-para">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 <span class="fixed">brk</span> system call to request more memory. When you free <a name="253"></a><a name="IDX-157"></a>memory it marks the block as unused so that future requests can retrieve it. In the <a class="chapterjump" href="http://www2.blogger.com/LiB0048.html#254" target="_parent">next section</a> we will look at building our own memory manager.</p></div> <div class="footnotes"> <div class="footnote"> <p><sup>[<a href="http://www2.blogger.com/post-edit.g?blogID=8901974503278002812&postID=3284968477063416573#N80" name="ftn.N80">5</a>]</sup>The function names usually aren't <span class="fixed">allocate</span> and <span class="fixed">deallocate</span>, but the functionality will be the same. In the C programming language, for example, they are named <span class="fixed">malloc</span> and <span class="fixed">free</span>.</p><div class="section"> <h2 class="first-section-title"><a name="254"></a><a name="ch09lev1sec5"></a>A Simple Memory Manager</h2> <p class="first-para">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.</p> <div class="informalexample"><pre class="literallayout"> #PURPOSE: Program to manage memory usage - allocates<br /># and deallocates memory as requested<br />#<br />#NOTES: The programs using these routines will ask<br /># for a certain size of memory. We actually<br /># use more than that size, but we put it<br /># at the beginning, before the pointer<br /># we hand back. We add a size field and<br /># an AVAILABLE/UNAVAILABLE marker. So, the<br /># memory looks like this<br />#<br /># #########################################################<br /># #Available Marker#Size of memory#Actual memory locations#<br /># #########################################################<br /># ^--Returned pointer<br /># points here<br /># The pointer we return only points to the actual<br /># locations requested to make it easier for the<br /># calling program. It also allows us to change our<br /># structure without the calling program having to<br /># change at all.<br /><br />.section .data<a name="255"></a><a name="IDX-158"></a><br />#######GLOBAL VARIABLES########<br /><br />#This points to the beginning of the memory we are managing<br />heap_begin:<br />.long 0<br /><br />#This points to one location past the memory we are managing<br />current_break:<br />.long 0<br /><br /><br /><br />######STRUCTURE INFORMATION####<br />#size of space for memory region header<br />.equ HEADER_SIZE, 8<br />#Location of the "available" flag in the header<br />.equ HDR_AVAIL_OFFSET, 0<br />#Location of the size field in the header<br />.equ HDR_SIZE_OFFSET, 4<br /><br /><br />###########CONSTANTS###########<br />.equ UNAVAILABLE, 0 #This is the number we will use to mark<br /> #space that has been given out<br />.equ AVAILABLE, 1 #This is the number we will use to mark<br /> #space that has been returned, and is<br /> #available for giving<br />.equ SYS_BRK, 45 #system call number for the break<br /> #system call<br /><br />.equ LINUX_SYSCALL, 0x80 #make system calls easier to read<br /><br /><br />.section .text<a name="256"></a><a name="IDX-159"></a><br />##########FUNCTIONS############<br /><br />##allocate_init##<br />#PURPOSE: call this function to initialize the<br /># functions (specifically, this sets heap_begin and<br /># current_break). This has no parameters and no<br /># return value.<br />.globl allocate_init<br />.type allocate_init, @function<br />allocate_init:<br />pushl %ebp #standard function stuff<br />movl %esp, %ebp<br /><br />#If the brk system call is called with 0 in %ebx, it<br />#returns the last valid usable address<br />movl $SYS_BRK, %eax #find out where the break is<br />movl $0, %ebx<br />int $LINUX_SYSCALL<br /><br />incl %eax #%eax now has the last valid<br /> #address, and we want the<br /> #memory location after that<br /><br />movl %eax, current_break #store the current break<br /><br />movl %eax, heap_begin #store the current break as our<br /> #first address. This will cause<br /> #the allocate function to get<br /> #more memory from Linux the<br /> #first time it is run<br /><br />movl %ebp, %esp #exit the function<br />popl %ebp<a name="257"></a><a name="IDX-160"></a><br />ret<br />#####END OF FUNCTION#######<br /><br /><br />##allocate##<br />#PURPOSE: This function is used to grab a section of<br /># memory. It checks to see if there are any<br /># free blocks, and, if not, it asks Linux<br /># for a new one.<br />#<br />#PARAMETERS: This function has one parameter - the size<br /># of the memory block we want to allocate<br />#<br />#RETURN VALUE:<br /># This function returns the address of the<br /># allocated memory in %eax. If there is no<br /># memory available, it will return 0 in %eax<br />#<br />######PROCESSING########<br />#Variables used:<br />#<br /># %ecx - hold the size of the requested memory<br /># (first/only parameter)<br /># %eax - current memory region being examined<br /># %ebx - current break position<br /># %edx - size of current memory region<br />#<br />#We scan through each memory region starting with<br />#heap_begin. We look at the size of each one, and if<br />#it has been allocated. If it's big enough for the<br />#requested size, and its available, it grabs that one.<br />#If it does not find a region large enough, it asks<br />#Linux for more memory. In that case, it moves<br />#current_break up<a name="258"></a><a name="IDX-161"></a><br />.globl allocate<br />.type allocate, @function<br />.equ ST_MEM_SIZE, 8 #stack position of the memory size<br /> #to allocate<br />allocate:<br />pushl %ebp #standard function stuff<br />movl %esp, %ebp<br /><br />movl ST_MEM_SIZE(%ebp), %ecx #%ecx will hold the size<br /> #we are looking for (which is the first<br /> #and only parameter)<br /><br />movl heap_begin, %eax #%eax will hold the current<br /> #search location<br /><br />movl current_break, %ebx #%ebx will hold the current<br /> #break<br /><br /><br />alloc_loop_begin: #here we iterate through each<br /> #memory region<br /><br />cmpl %ebx, %eax #need more memory if these are equal<br />je move_break<br /><br />#grab the size of this memory<br />movl HDR_SIZE_OFFSET(%eax), %edx<br />#If the space is unavailable, go to the<br />cmpl $UNAVAILABLE, HDR_AVAIL_OFFSET(%eax)<br />je next_location #next one<br /><br />cmpl %edx, %ecx #If the space is available, compare<br />jle allocate_here #the size to the needed size. If its<br /> #big enough, go to allocate_here<a name="259"></a><a name="IDX-162"></a><br />next_location:<br />addl $HEADER_SIZE, %eax #The total size of the memory<br />addl %edx, %eax #region is the sum of the size<br /> #requested (currently stored<br /> #in %edx), plus another 8 bytes<br /> #for the header (4 for the<br /> #AVAILABLE/UNAVAILABLE flag,<br /> #and 4 for the size of the<br /> #region). So, adding %edx and $8<br /> #to %eax will get the address<br /> #of the next memory region<br /><br />jmp alloc_loop_begin #go look at the next location<br /><br />allocate_here: #if we've made it here,<br /> #that means that the<br /> #region header of the region<br /> #to allocate is in %eax<br /><br />#mark space as unavailable<br />movl $UNAVAILABLE, HDR_AVAIL_OFFSET(%eax)<br />addl $HEADER_SIZE, %eax #move %eax past the header to<br /> #the usable memory (since<br /> #that's what we return)<br /><br />movl %ebp, %esp #return from the function<br />popl %ebp<br />ret<br /><br /><br />move_break: #if we've made it here, that<br /> #means that we have exhausted<br /> #all addressable memory, and<br /> #we need to ask for more.<br /> #%ebx holds the current<a name="260"></a><a name="IDX-163"></a><br /> #endpoint of the data,<br /> #and %ecx holds its size<br /><br /> #we need to increase %ebx to<br /> #where we _want_ memory<br /> #to end, so we<br />addl $HEADER_SIZE, %ebx #add space for the headers<br /> #structure<br />addl %ecx, %ebx #add space to the break for<br /> #the data requested<br /><br /> #now its time to ask Linux<br /> #for more memory<br /><br />pushl %eax #save needed registers<br />pushl %ecx<br />pushl %ebx<br /><br />movl $SYS_BRK, %eax #reset the break (%ebx has<br /> #the requested break point)<br />int $LINUX_SYSCALL<br /> #under normal conditions, this should<br /> #return the new break in %eax, which<br /> #will be either 0 if it fails, or<br /> #it will be equal to or larger than<br /> #we asked for. We don't care<br /> #in this program where it actually<br /> #sets the break, so as long as %eax<br /> #isn't 0, we don't care what it is<br /><br />cmpl $0, %eax #check for error conditions<br />je error<br /><br />popl %ebx #restore saved registers<br />popl %ecx<a name="261"></a><a name="IDX-164"></a><br />popl %eax<br /><br />#set this memory as unavailable, since we're about to<br />#give it away<br />movl $UNAVAILABLE, HDR_AVAIL_OFFSET(%eax)<br />#set the size of the memory<br />movl %ecx, HDR_SIZE_OFFSET(%eax)<br /><br />#move %eax to the actual start of usable memory.<br />#%eax now holds the return value<br />addl $HEADER_SIZE, %eax<br /><br />movl %ebx, current_break #save the new break<br /><br />movl %ebp, %esp #return the function<br />popl %ebp<br />ret<br /><br />error:<br />movl $0, %eax #on error, we return zero<br />movl %ebp, %esp<br />popl %ebp<br />ret<br />########END OF FUNCTION########<br /><br /><br />##deallocate##<br />#PURPOSE:<br /># The purpose of this function is to give back<br /># a region of memory to the pool after we're done<br /># using it.<br />#<br />#PARAMETERS:<br /># The only parameter is the address of the memory<br /># we want to return to the memory pool.<a name="262"></a><a name="IDX-165"></a><br />#<br />#RETURN VALUE:<br /># There is no return value<br />#PROCESSING:<br /># If you remember, we actually hand the program the<br /># start of the memory that they can use, which is<br /># 8 storage locations after the actual start of the<br /># memory region. All we have to do is go back<br /># 8 locations and mark that memory as available,<br /># so that the allocate function knows it can use it.<br />.globl deallocate<br />.type deallocate, @function<br />#stack position of the memory region to free<br />.equ ST_MEMORY_SEG, 4<br />deallocate:<br />#since the function is so simple, we<br />#don't need any of the fancy function stuff<br /><br />#get the address of the memory to free<br />#(normally this is 8(%ebp), but since<br />#we didn't push %ebp or move %esp to<br />#%ebp, we can just do 4(%esp)<br />movl ST_MEMORY_SEG(%esp), %eax<br /><br /><br />#get the pointer to the real beginning of the memory<br />subl $HEADER_SIZE, %eax<br /><br />#mark it as available<br />movl $AVAILABLE, HDR_AVAIL_OFFSET(%eax)<br /><br />#return<br />ret<br />########END OF FUNCTION##########<br /><a name="263"></a><a name="IDX-166"></a><br /></pre></div> <p class="para">The first thing to notice is that there is no <span class="fixed">_start</span> 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.</p> <p class="para">To assemble the program, do the following:</p> <div class="informalexample"><pre class="literallayout">as alloc.s -o alloc.o<br /></pre></div> <p class="para">Okay, now let's look at the code.</p> <div class="section"> <h3 class="sect3-title"><a name="264"></a><a name="ch09lev2sec1"></a>Variables and Constants</h3> <p class="first-para">At the beginning of the program, we have two locations set up:</p> <div class="informalexample"><pre class="literallayout">heap_begin:<br />.long 0<br /><br />current_break:<br />.long 0<br /></pre></div> <p class="para">Remember, the section of memory being managed is commonly referred to as the <i class="emphasis">heap.</i> 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.</p> <p class="para">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 <a name="265"></a><a name="IDX-167"></a>well as the location of the next memory region. The following constants describe this record:</p> <div class="informalexample"><pre class="literallayout"> .equ HEADER_SIZE, 8<br />.equ HDR_AVAIL_OFFSET, 0<br />.equ HDR_SIZE_OFFSET, 4<br /></pre></div> <p class="para">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.</p> <p class="para">The values that we will use for our <span class="fixed">available</span> field are either 0 for unavailable, or 1 for available. To make this easier to read, we have the following definitions:</p> <div class="informalexample"><pre class="literallayout"> .equ UNAVAILABLE, 0<br />.equ AVAILABLE, 1<br /></pre></div> <p class="para">Finally, we have our Linux system call definitions:</p> <div class="informalexample"><pre class="literallayout"> .equ BRK, 45<br />.equ LINUX_SYSCALL, 0x80<br /></pre></div></div> <div class="section"> <h3 class="sect3-title"><a name="266"></a><a name="ch09lev2sec2"></a>The <span class="fixed">allocate_init</span> Function</h3> <p class="first-para">Okay, this is a simple function. All it does is set up the <span class="fixed">heap_begin</span> and <span class="fixed">current_break</span> variables we discussed earlier. So, if you remember the discussion earlier, the current break can be found using the <span class="fixed">brk</span> system call. So, the function starts like this:</p> <div class="informalexample"><pre class="literallayout"> pushl %ebp<br />movl %esp, %ebp<br /><br />movl $SYS_BRK, %eax<a name="267"></a><a name="IDX-168"></a><br />movl $0, %ebx<br />int $LINUX_SYSCALL<br /></pre></div> <p class="para">Anyway, after <span class="fixed">int $LINUX_SYSCALL, %eax</span> holds the last valid address. We actually want the first invalid address instead of the last valid address, so we just increment <span class="fixed">%eax</span>. Then we move that value to the <span class="fixed">heap_begin</span> and <span class="fixed">current_break</span> locations. Then we leave the function. The code looks like this:</p> <div class="informalexample"><pre class="literallayout"> incl %eax<br />movl %eax, current_break<br />movl %eax, heap_begin<br />movl %ebp, %esp<br />popl %ebp<br />ret<br /></pre></div> <p class="last-para">The heap consists of the memory between <span class="fixed">heap_begin</span> and <span class="fixed">current_break,</span> so this says that we start off with a heap of zero bytes. Our <span class="fixed">allocate</span> function will then extend the heap as much as it needs to when it is called.</p></div> <div class="section"> <h3 class="sect3-title"><a name="268"></a><a name="ch09lev2sec3"></a>The <span class="fixed">allocate</span> Function</h3> <p class="first-para">This is the doozy function. Let's start by looking at an outline of the function:</p> <ol class="orderedlist"><li class="first-listitem"> <p class="first-para">Start at the beginning of the heap.</p> </li><li class="listitem"> <p class="first-para">Check to see if we're at the end of the heap.</p> </li><li class="listitem"> <p class="first-para">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.</p> </li><li class="listitem"> <p class="first-para">If the current memory region is marked "unavailable", go to the next one, and go back to step 2.</p> </li><li class="listitem"> <p class="first-para">If the current memory region is too small to hold the requested amount of space, go back to step 2.</p><a name="269"></a><a name="IDX-169"></a> </li><li class="listitem"> <p class="first-para">If the memory region is available and large enough, mark it as "unavailable" and return it.</p></li></ol> <p class="para">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.</p> <p class="para">Now that you've looked back through the code, let's examine it one line at a time. We start off like this:</p> <div class="informalexample"><pre class="literallayout"> pushl %ebp<br />movl %esp, %ebp<br />movl ST_MEM_SIZE(%ebp), %ecx<br />movl heap_begin, %eax<br />movl current_break, %ebx<br /></pre></div> <p class="para">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.</p> <p class="para">The <a class="internaljump" href="http://www2.blogger.com/post-edit.g?blogID=8901974503278002812&postID=3284968477063416573#ch09lev2sec4">next section</a> is marked <span class="fixed">alloc_loop_begin</span>. 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:</p> <div class="informalexample"><pre class="literallayout"> cmpl %ebx, %eax<br />je move_break<br /></pre></div> <p class="para"><span class="fixed">%eax</span> holds the current memory region being examined and <span class="fixed">%ebx</span> 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 <span class="fixed">move_break</span> and see what happens there:</p> <div class="informalexample"><pre class="literallayout">move_break:<br />addl $HEADER_SIZE, %ebx<br />addl %ecx, %ebx<a name="270"></a><a name="IDX-170"></a><br />pushl %eax<br />pushl %ecx<br />pushl %ebx<br />movl $SYS_BRK, %eax<br />int $LINUX_SYSCALL<br /></pre></div> <p class="para">When we reach this point in the code, <span class="fixed">%ebx</span> holds where we want the next region of memory to be. So, we add our header size and region size to <span class="fixed">%ebx</span>, 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 <span class="fixed">brk</span> system call. After that we check for errors:</p> <div class="informalexample"><pre class="literallayout"> cmpl $0, %eax<br />je error<br /></pre></div> <p class="para">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 <span class="fixed">%eax</span> points to the start of usable memory (which is <i class="emphasis">after</i> the header).</p> <div class="informalexample"><pre class="literallayout"> popl %ebx<br />popl %ecx<br />popl %eax<br />movl $UNAVAILABLE, HDR_AVAIL_OFFSET(%eax)<br />movl %ecx, HDR_SIZE_OFFSET(%eax)<br />addl $HEADER_SIZE, %eax<br /></pre></div> <p class="para">Then we store the new program break and return the pointer to the allocated memory.</p> <div class="informalexample"><pre class="literallayout"> movl %ebx, current_break<br />movl %ebp, %esp<br />popl %ebp<br />ret<br /></pre></div> <p class="para">The <span class="fixed">error</span> code just returns 0 in <span class="fixed">%eax</span>, so we won't discuss it.</p><a name="271"></a><a name="IDX-171"></a> <p class="para">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.</p> <div class="informalexample"><pre class="literallayout"> movl HDR_SIZE_OFFSET(%eax), %edx<br />cmpl $UNAVAILABLE, HDR_AVAIL_OFFSET(%eax)<br />je next_location<br /></pre></div> <p class="para">This first grabs the size of the memory region and puts it in <span class="fixed">%edx</span>. Then it looks at the available flag to see if it is set to <span class="fixed">UNAVAILABLE</span>. 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 <span class="fixed">UNAVAILABLE</span>, you go to the code labeled <span class="fixed">next_location</span>. If the available flag is set to <span class="fixed">AVAILABLE</span>, then we keep on going.</p> <p class="para">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 <span class="fixed">%edx</span>, so we do this:</p> <div class="informalexample"><pre class="literallayout"> cmpl %edx, %ecx<br />jle allocate_here<br /></pre></div> <p class="para">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 <span class="fixed">allocate_here</span> and see what happens:</p> <div class="informalexample"><pre class="literallayout"> movl $UNAVAILABLE, HDR_AVAIL_OFFSET(%eax)<br />addl $HEADER_SIZE, %eax<br />movl %ebp, %esp<br />popl %ebp<br />ret<br /></pre></div> <p class="para">It marks the memory as being unavailable. Then it moves the pointer <span class="fixed">%eax</span> 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.</p><a name="272"></a><a name="IDX-172"></a> <p class="para">Okay, so let's say the region wasn't big enough. What then? Well, we would then be at the code labeled <span class="fixed">next_location</span>. 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 <span class="fixed">%eax</span> to the next possible memory region, and goes back to the beginning of the loop. Remember that <span class="fixed">%edx</span> is holding the size of the current memory region, and <span class="fixed">HEADER_SIZE </span>is the symbol for the size of the memory region's header. So this code will move us to the next memory region:</p> <div class="informalexample"><pre class="literallayout"> addl $HEADER_SIZE, %eax<br />addl %edx, %eax<br />jmp alloc_loop_begin<br /></pre></div> <p class="para">And now the function runs another loop.</p> <p class="para">Whenever you have a loop, you must make sure that it will <i class="emphasis">always</i> 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:</p> <ul class="itemizedlist"><li class="first-listitem"> <p class="first-para">We will reach the end of the heap</p> </li><li class="listitem"> <p class="first-para">We will find a memory region that's available and large enough</p> </li><li class="listitem"> <p class="first-para">We will go to the next location</p></li></ul> <p class="last-para">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.</p></div> <div class="section"> <h3 class="sect3-title"><a name="273"></a><a name="ch09lev2sec4"></a>The <span class="fixed">deallocate</span> Function</h3> <p class="first-para">The <span class="fixed">deallocate</span> function is much easier than the <span class="fixed">allocate</span> one. That's because it doesn't have to do any searching at all. It can just mark the current memory <a name="274"></a><a name="IDX-173"></a>region as <span class="fixed">AVAILABLE</span>, and <span class="fixed">allocate</span> will find it next time it is called. So we have:</p> <div class="informalexample"><pre class="literallayout"> movl ST_MEMORY_SEG(%esp), %eax<br />subl $HEADER_SIZE, %eax<br />movl $AVAILABLE, HDR_AVAIL_OFFSET(%eax)<br />ret<br /></pre></div> <p class="last-para">In this function, we don't have to save <span class="fixed">%ebp</span> or <span class="fixed">%esp</span> 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 <span class="fixed">%eax</span>.</p></div> <div class="section"> <h3 class="sect3-title"><a name="275"></a><a name="ch09lev2sec5"></a>Performance Issues and Other Problems</h3> <p class="first-para">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.</p> <p class="para">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. <sup>[<a href="http://www2.blogger.com/post-edit.g?blogID=8901974503278002812&postID=3284968477063416573#ftn.N505" name="N505">6</a>]</sup> This method is said to run in <i class="emphasis">linear</i> time, which means that every element you have to manage makes your program <a name="276"></a><a name="IDX-174"></a>take longer. A program that runs in <i class="emphasis">constant</i> time takes the same amount of time no matter how many elements you are managing. Take the <span class="fixed">deallocate</span> 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 <span class="fixed">allocate</span> function is one of the slowest of all memory managers, the <span class="fixed">deallocate</span> function is one of the fastest.</p> <p class="para">Another performance problem is the number of times we're calling the <span class="fixed">brk</span> 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 <i class="emphasis">kernel mode,</i> then Linux maps the memory, and then switches back to <i class="emphasis">user mode</i> for your application to continue running. This is also called a <i class="emphasis">context switch.</i> Context switches are relatively slow on x86 processors. Generally, you should avoid calling the kernel unless you really need to.</p> <p class="para">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 <span class="fixed">brk</span> system calls when we already have the memory mapped in.</p> <p class="last-para">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.</p></div></div> <div class="footnotes"> <div class="footnote"> <p><sup>[<a href="http://www2.blogger.com/post-edit.g?blogID=8901974503278002812&postID=3284968477063416573#N505" name="ftn.N505">6</a>]</sup>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.</p><div class="section"> <h2 class="first-section-title"><a name="277"></a><a name="ch09lev1sec6"></a>Using Our Allocator</h2><a name="278"></a><a name="IDX-175"></a> <p class="para">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 <span class="fixed">.bss</span>.</p> <p class="para">The program we will demonstrate this on is <span class="fixed">read-records.s</span> from <span class="chapterjump">Chapter 6</span>. This program uses a buffer named <span class="fixed">record_buffer</span> to handle its input/output needs. We will simply change this from being a buffer defined in .<span class="fixed">bss</span> 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.</p> <p class="para">The first change we need to make is in the declaration. Currently it looks like this:</p> <div class="informalexample"><pre class="literallayout"> .section .bss<br />.lcomm, record_buffer, RECORD_SIZE<br /></pre></div> <p class="para">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 <span class="fixed">.data</span> section and look like this:</p> <div class="informalexample"><pre class="literallayout">record_buffer_ptr:<br />.long 0<br /></pre></div> <p class="para">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:</p> <div class="informalexample"><pre class="literallayout"> call allocate_init<br /></pre></div> <p class="para">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 <a name="279"></a><a name="IDX-176"></a>reading. Therefore, we will call <span class="fixed">allocate</span> to allocate this memory, and then save the pointer it returns into <span class="fixed">record_buffer_ptr</span>. Like this:</p> <div class="informalexample"><pre class="literallayout"> pushl $RECORD_SIZE<br />call allocate<br />movl %eax, record_buffer_ptr<br /></pre></div> <p class="para">Now, when we make the call to <span class="fixed">read_record</span>, it is expecting a pointer. In the old code, the pointer was the immediate-mode reference to <span class="fixed">record_buffer</span>. Now, <span class="fixed">record_buffer_ptr</span> just holds the pointer rather than the buffer itself. Therefore, we must do a direct mode load to get the value in <span class="fixed">record_buffer_ptr</span>. We need to remove this line:</p> <div class="informalexample"><pre class="literallayout">pushl $record_buffer<br /></pre></div> <p class="para">And put this line in its place:</p> <div class="informalexample"><pre class="literallayout">pushl record_buffer_ptr<br /></pre></div> <p class="para">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 <span class="fixed">$RECORD_FIRSTNAME + record_buffer</span>. 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 <span class="fixed">record_buffer_ptr</span>. To get that value, we will need to move the pointer into a register, and then add <span class="fixed">$RECORD_FIRSTNAME</span> to it to get the pointer. So where we have the following code:</p> <div class="informalexample"><pre class="literallayout"> pushl $RECORD_FIRSTNAME + record_buffer<br /></pre></div> <p class="para">We need to replace it with this:</p> <div class="informalexample"><pre class="literallayout"> movl record_buffer_ptr, %eax<br />addl $RECORD_FIRSTNAME, %eax<br />pushl %eax<br /><a name="280"></a><a name="IDX-177"></a><br /></pre></div> <p class="para">Similarly, we need to change the line that says</p> <div class="informalexample"><pre class="literallayout"> movl $RECORD_FIRSTNAME + record_buffer, %ecx<br /></pre></div> <p class="para">so that it reads like this:</p> <div class="informalexample"><pre class="literallayout"> movl record_buffer_ptr, %ecx<br />addl $RECORD_FIRSTNAME, %ecx<br /></pre></div> <p class="para">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 <span class="fixed">record_buffer_ptr</span> to the <span class="fixed">deallocate</span> function right before exitting:</p> <div class="informalexample"><pre class="literallayout"> pushl record_buffer_ptr<br />call deallocate<br /></pre></div> <p class="para">Now you can build your program with the following commands:</p> <div class="informalexample"><pre class="literallayout">as read-records.s -o read-records.o<br />ld alloc.o read-record.o read-records.o write-newline.o count-<br />chars.o -o read-records<br /></pre></div> <p class="para">You can then run your program by doing <span class="fixed">./read-records.</span> </p> <p class="last-para">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.</p><h2 class="first-section-title"><a name="281"></a><a name="ch09lev1sec7"></a>More Information</h2> <p class="first-para">More information on memory handling in Linux and other operating systems can be found at the following locations:</p><a name="282"></a><a name="IDX-178"></a> <ul class="itemizedlist"><li class="first-listitem"> <p class="first-para">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 <a class="url" href="http://linuxassembly.org/startup.html" target="_top">http://linuxassembly.org/startup.html</a> </p> </li><li class="listitem"> <p class="first-para">A good overview of virtual memory in many different systems is available at <a class="url" href="http://cne.gmu.edu/modules/vm/" target="_top">http://cne.gmu.edu/modules/vm/</a> </p> </li><li class="listitem"> <p class="first-para">Several in-depth articles on Linux's virtual memory subsystem is available at <a class="url" href="http://www.nongnu.org/lkdp/files.html" target="_top">http://www.nongnu.org/lkdp/files.html</a> </p> </li><li class="listitem"> <p class="first-para">Doug Lea has written up a description of his popular memory allocator at <a class="url" href="http://gee.cs.oswego.edu/dl/html/malloc.html" target="_top">http://gee.cs.oswego.edu/dl/html/malloc.html</a> </p> </li><li class="listitem"> <p class="first-para">A paper on the 4.4 BSD memory allocator is available at <a class="url" href="http://docs.freebsd.org/44doc/papers/malloc.html" target="_top">http://docs.freebsd.org/44doc/papers/malloc.html</a></p></li></ul><br /><div class="section"> <h2 class="first-section-title"><a name="283"></a><a name="ch09lev1sec8"></a>Review</h2> <div class="section"> <h3 class="sect3-title"><a name="284"></a><a name="ch09lev2sec6"></a>Know the Concepts</h3> <ul class="itemizedlist"><li class="first-listitem"> <p class="first-para">Describe the layout of memory when a Linux program starts.</p> </li><li class="listitem"> <p class="first-para">What is the heap?</p> </li><li class="listitem"> <p class="first-para">What is the current break?</p> </li><li class="listitem"> <p class="first-para">Which direction does the stack grow in?</p> </li><li class="listitem"> <p class="first-para">Which direction does the heap grow in?</p> </li><li class="listitem"> <p class="first-para">What happens when you access unmapped memory?</p> </li><li class="listitem"> <p class="first-para">How does the operating system prevent processes from writing over each other's memory?</p> </li><li class="listitem"> <p class="first-para">Describe the process that occurs if a piece of memory you are using is currently residing on disk?</p><a name="285"></a><a name="IDX-179"></a> </li><li class="listitem"> <p class="first-para">Why do you need an allocator?</p></li></ul></div> <div class="section"> <h3 class="sect3-title"><a name="286"></a><a name="ch09lev2sec7"></a>Use the Concepts</h3> <ul class="itemizedlist"><li class="first-listitem"> <p class="first-para">Modify the memory manager so that it calls <span class="fixed">allocate_init</span> automatically if it hasn't been initialized.</p> </li><li class="listitem"> <p class="first-para">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.</p> </li><li class="listitem"> <p class="first-para">Modify one of your programs that uses buffers to use the memory manager to get buffer memory rather than using the <span class="fixed">.bss</span>.</p></li></ul></div> <div class="section"> <h3 class="sect3-title"><a name="287"></a><a name="ch09lev2sec8"></a>Going Further</h3> <ul class="itemizedlist"><li class="first-listitem"> <p class="first-para">Research <i class="emphasis">garbage collection.</i> What advantages and disadvantages does this have over the style of memory management used here?</p> </li><li class="listitem"> <p class="first-para">Research <i class="emphasis">reference counting.</i> What advantages and disadvantages does this have over the style of memory management used here?</p> </li><li class="listitem"> <p class="first-para">Change the name of the functions to <span class="fixed">malloc</span> and <span class="fixed">free</span>, and build them into a shared library. Use <span class="fixed">LD_PRELOAD</span> to force them to be used as your memory manager instead of the default one. Add some <span class="fixed">write</span> system calls to STDOUT to verify that your memory manager is being used instead of the default one.</p></li></ul><a name="288"></a><a name="IDX-180"></a></div></div><br /></div></div></div></div></div></div></div></div></div></div></div></div></div><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8901974503278002812-3284968477063416573?l=programminggroundup.blogspot.com'/></div>Adminhttp://www.blogger.com/profile/13783659974416042562noreply@blogger.com0tag:blogger.com,1999:blog-8901974503278002812.post-21143397050575272302007-01-31T18:22:00.000-08:002007-01-31T20:20:50.276-08:00Chapter 8: Sharing Functions with Code Libraries<div class="section"> <h2 class="sect2-title"><a name="209"></a>Overview</h2><a name="210"></a><a name="IDX-129"></a> <p class="para">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:</p> <ul class="itemizedlist"><li class="first-listitem"> <p class="first-para">Write code in a high-level language instead of assembly language</p> </li><li class="listitem"> <p class="first-para">Have lots of pre-written code that you can cut and paste into your own programs</p> </li><li class="listitem"> <p class="first-para">Have a set of functions on the system that are shared among any program that wishes to use it</p></li></ul> <p class="para">All three of these are usually used to some degree in any given project. The first option will be explored further in <span class="chapterjump">Chapter 11</span>. The second option is useful but it suffers from some drawbacks, including:</p> <ul class="itemizedlist"><li class="first-listitem"> <p class="first-para">Code that is copied often has to be majorly modified to fit the surrounding code.</p> </li><li class="listitem"> <p class="first-para">Every program containing the copied code has the same code in it, thus wasting a lot of space.</p> </li><li class="listitem"> <p class="first-para">If a bug is found in any of the copied code it has to be fixed in every application program.</p></li></ul> <p class="para">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 <i class="emphasis">dynamic libraries</i> which contain the functions they need.</p><a name="211"></a><a name="IDX-130"></a> <p class="para">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:</p> <ul class="itemizedlist"><li class="first-listitem"> <p class="first-para">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?</p> </li><li class="listitem"> <p class="first-para">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.</p></li></ul> <p class="para">These problems are what lead to what is known as "DLL hell". However, it is generally assumed that the advantages outweigh the disadvantages.</p> <p class="last-para">In programming, these shared code files are referred to as <i class="emphasis">shared libraries</i> , <i class="emphasis">dynamic libraries, shared objects, dynamic-link libraries, DLLs,</i> or <i class="emphasis">.so files</i>.<sup>[<a href="http://www2.blogger.com/post-edit.g?blogID=8901974503278002812&postID=2114339705057527230#ftn.N84" name="N84">1</a>]</sup> We will refer to all of these as <i class="emphasis">dynamic libraries.</i> </p></div> <div class="footnotes"> <div class="footnote"> <p><sup>[<a href="http://www2.blogger.com/post-edit.g?blogID=8901974503278002812&postID=2114339705057527230#N84" name="ftn.N84">1</a>]</sup>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 <i class="citetitle">position-independent code</i> (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.</p><div class="section"> <h2 class="first-section-title"><a name="212"></a><a name="ch08lev1sec1"></a>Using a Dynamic Library</h2> <p class="first-para">The program we will examine here is simple - it writes the characters <span class="fixed">hello world</span> to the screen and exits. The regular program, <span class="fixed">helloworld-nolib. s</span>, looks like this:</p><a name="213"></a><a name="IDX-131"></a> <div class="informalexample"><pre class="literallayout">#PURPOSE: This program writes the message "hello world" and<br /># exits<br />#<br /><br />.include "linux.s"<br /><br />.section .data<br /><br /><br />helloworld:<br />.ascii "hello world\n"<br />helloworld_end:<br /><br />.equ helloworld_len, helloworld_end - helloworld<br /><br />.section .text<br />.globl _start<br />_start:<br />movl $STDOUT, %ebx<br />movl $helloworld, %ecx<br />movl $helloworld_len, %edx<br />movl $SYS_WRITE, %eax<br />int $LINUX_SYSCALL<br /><br />movl $0, %ebx<br />movl $SYS_EXIT, %eax<br />int $LINUX_SYSCALL<br /></pre></div> <p class="para">That's not too long. However, take a look at how short <span class="fixed">helloworld-lib</span> is which uses a library:</p> <div class="informalexample"><pre class="literallayout">#PURPOSE: This program writes the message "hello world" and<br /># exits<a name="214"></a><a name="IDX-132"></a><br />#<br /><br />.section .data<br /><br />helloworld:<br />.ascii "hello world\n\0"<br /><br />.section .text<br />.globl _start<br />_start:<br />pushl $helloworld<br />call printf<br /><br />pushl $0<br />call exit<br /></pre></div> <p class="para">It's even shorter!</p> <p class="para">Now, building programs which use dynamic libraries is a little different than normal. You can build the first program normally by doing this:</p> <div class="informalexample"><pre class="literallayout">as helloworld-nolib.s -o helloworld-nolib.o<br />ld helloworld-nolib.o -o helloworld-nolib<br /></pre></div> <p class="para">However, in order to build the second program, you have to do this:</p> <div class="informalexample"><pre class="literallayout">as helloworld-lib.s -o helloworld-lib.o<br />ld -dynamic-linker /lib/ld-linux.so.2 \<br /> -o helloworld-lib helloworld-lib.o -1c<br /></pre></div> <p class="para">Remember, the backslash in the first line simply means that the command continues on the next line. The option <span class="fixed">-dynamic-linker /lib/ld-linux.so.2</span> allows our program to be linked to libraries. This builds the executable so that before executing, the operating system will load the <a name="215"></a><a name="IDX-133"></a>program <span class="fixed">/lib/ld-linux.so.2</span> to load in external libraries and link them with the program. This program is known as a <i class="emphasis">dynamic linker</i>.</p> <p class="para">The <span class="fixed">-lc</span> option says to link to the <span class="fixed">c</span> library, named <span class="fixed">libc.so</span> on GNU/Linux systems. Given a library name, <span class="fixed">c</span> in this case (usually library names are longer than a single letter), the GNU/Linux linker prepends the string <span class="fixed">lib</span> to the beginning of the library name and appends <span class="fixed">.so</span> 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 <span class="fixed">printf</span>, which prints strings, and <span class="fixed">exit</span>, which exits the program.</p> <p class="last-para">Notice that the symbols <span class="fixed">printf</span> and <span class="fixed">exit</span> 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.</p><h2 class="first-section-title"><a name="216"></a><a name="ch08lev1sec2"></a>How Dynamic Libraries Work</h2> <p class="first-para">In our first programs, all of the code was contained within the source file. Such programs are called <i class="emphasis">statically-linked executables</i>, because they contained all of the necessary functionality for the program that wasn't handled by the kernel. In the programs we wrote in <span class="chapterjump">Chapter 6</span>, 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 <span class="fixed">helloworld-lib</span> program, we started using dynamic libraries. When you use dynamic libraries, your program is then <i class="emphasis">dynamically-linked,</i> which <a name="217"></a><a name="IDX-134"></a>means that not all of the code needed to run the program is actually contained within the program file itself, but in external libraries.</p> <p class="para">When we put the <span class="fixed">-lc</span> on the command to link the <span class="fixed">helloworld</span> program, it told the linker to use the <span class="fixed">c</span> library (<span class="fixed">libc.so</span>) to look up any symbols that weren't already defined in <span class="fixed">helloworld.o</span>. However, it doesn't actually add any code to our program, it just notes in the program where to look. When the <span class="fixed">helloworld</span> program begins, the file <span class="fixed">/lib/ld-linux.so.2</span> is loaded first. This is the dynamic linker. This looks at our <span class="fixed">helloworld</span> program and sees that it needs the <span class="fixed">c</span> library to run. So, it searches for a file called <span class="fixed">libc.so</span> in the standard places (listed in <span class="fixed">/etc/ld.so.conf</span> and in the contents of the <span class="fixed">LD_LIBRARY_PATH</span> environment variable), then looks in it for all the needed symbols (<span class="fixed">printf</span> and <span class="fixed">exit</span> in this case), and then loads the library into the program's virtual memory. Finally, it replaces all instances of <span class="fixed">printf</span> in the program with the actual location of <span class="fixed">printf</span> in the library.</p> <p class="para">Run the following command:</p> <div class="informalexample"><pre class="literallayout">ldd ./helloworld-nolib<br /></pre></div> <p class="para">It should report back <span class="fixed">not a dynamic executable</span>. This is just like we said - <span class="fixed">helloworld-nolib</span> is a statically-linked executable. However, try this:</p> <div class="informalexample"><pre class="literallayout">ldd ./helloworld-lib<br /></pre></div> <p class="para">It will report back something like</p> <div class="informalexample"><pre class="literallayout"> libc.so.6 => /lib/libc.so.6 (0x4001d000)<br /> /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x400000000)<br /></pre></div> <p class="last-para">The numbers in parenthesis may be different on your system. This means that the program <span class="fixed">helloworld</span> is linked to <span class="fixed">libc.so.6</span> (the <span class="fixed">.6</span> is the version number), which is found at <span class="fixed">/lib/libc.so.6</span>, and <span class="fixed">/lib/ld-linux.so.2</span> is found at <span class="fixed">/lib/ld-linux.so.2</span>. These libraries have to be loaded before the program can <a name="218"></a><a name="IDX-135"></a>be run. If you are interested, run the <span class="fixed">ldd</span> program on various programs that are on your Linux distribution, and see what libraries they rely on.</p><div class="chapter"><a name="ch08"></a> <div class="section"> <h2 class="first-section-title"><a name="219"></a><a name="ch08lev1sec3"></a>Finding Information About Libraries</h2> <p class="first-para">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 <span class="fixed">printf</span>. Its calling interface (usually referred to as a <i class="emphasis">prototype</i>) looks like this:</p> <div class="informalexample"><pre class="literallayout">int printf(char *string, ...);<br /></pre></div> <p class="para">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 <span class="fixed">printf</span> function above is described using the C programming language.</p> <p class="para">This definition means that there is a function <span class="fixed">printf</span>. The things inside the parenthesis are the function's parameters or arguments. The first parameter here is <span class="fixed">char *string</span>. This means there is a parameter named <span class="fixed">string</span> (the name isn't important, except to use for talking about it), which has a type <span class="fixed">char *.char</span> 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 <span class="fixed">helloworld program</span>, you will notice that the function call looked like this:</p> <div class="informalexample"><pre class="literallayout"> pushl $hello<br />call printf<br /></pre></div> <p class="para">So, we pushed the address of the <span class="fixed">hello</span> string, rather than the actual characters. You might notice that we didn't push the length of the string. The way that <span class="fixed">printf</span> found the end of the string was because we ended it with a null character <a name="220"></a><a name="IDX-136"></a><span class="fixed">(\0)</span>. Many functions work that way, especially C language functions. The <span class="fixed">int</span> before the function definition tell what type of value the function will return in <span class="fixed">%eax</span> when it returns. <span class="fixed">printf</span> will return an <span class="fixed">int</span> when it's through. Now, after the <span class="fixed">char *string</span>, 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. <span class="fixed">printf</span>, however, can take many. It will look into the <span class="fixed">string</span> parameter, and everywhere it sees the characters <span class="fixed">%s</span>, it will look for another string from the stack to insert, and everywhere it sees <span class="fixed">%d</span> it will look for a number from the stack to insert. This is best described using an example:</p> <div class="informalexample"><pre class="literallayout">#PURPOSE: This program is to demonstrate how to call printf<br />#<br /><br />.section .data<br /><br />#This string is called the format string. It's the first<br />#parameter, and printf uses it to find out how many parameters<br />#it was given, and what kind they are.<br />firststring:<br />.ascii "Hello! %s is a %s who loves the number %d\n\0"<br />name:<br />.ascii "Jonathan\0"<br />personstring:<br />.ascii "person\0"<br />#This could also have been an .equ, but we decided to give it<br />#a real memory location just for kicks<br />numberloved:<br />.long 3<br /><br />.section .text<br />.globl _start<br />_start:<br />#note that the parameters are passed in the<br />#reverse order that they are listed in the<br />#function's prototype.<a name="221"></a><a name="IDX-137"></a><br />pushl numberloved #This is the %d<br />pushl $personstring #This is the second %s<br />pushl $name #This is the first %s<br />pushl $firststring #This is the format string<br /> #in the prototype<br />call printf<br /><br />pushl $0<br />call exit<br /></pre></div> <p class="para">Type it in with the filename <span class="fixed">printf-example.s</span>, and then do the following commands:</p> <div class="informalexample"><pre class="literallayout">as printf-example.s -o printf-example.o<br />ld printf-example.o -o printf-example -lc \<br /> -dynamic-linker /lib/ld-linux.so.2<br /></pre></div> <p class="para">Then run the program with <span class="fixed">./printf-example</span>, and it should say this:</p> <div class="informalexample"><pre class="literallayout">Hello! Jonathan is a person who loves the number 3<br /></pre></div> <p class="para">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.<sup>[<a href="http://www2.blogger.com/post-edit.g?blogID=8901974503278002812&postID=2114339705057527230#ftn.N148" name="N148">2</a>]</sup> You may be wondering how the <span class="fixed">printf</span> function knows how many parameters there are. Well, it searches through your string, and counts how many <span class="fixed">%d</span>s and <span class="fixed">%s</span>s it finds, and then grabs that number of parameters from the stack. If the parameter matches a <span class="fixed">%d</span>, it treats it as a number, and if it <a name="222"></a><a name="IDX-138"></a>matches a <span class="fixed">%s</span>, it treats it as a pointer to a null-terminated string. <span class="fixed">printf</span> has many more features than this, but these are the most-used ones. So, as you can see, <span class="fixed">printf</span> 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.</p> <p class="para">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:</p> <p class="para"><span class="fixed">int</span> </p> <ul class="simple-list"><li class="first-listitem"> <p class="first-para">An <span class="fixed">int</span> is an integer number (4 bytes on x86 processor).</p></li></ul> <p class="para"><span class="fixed">long</span> </p> <ul class="simple-list"><li class="first-listitem"> <p class="first-para">A <span class="fixed">long</span> is also an integer number (4 bytes on an x86 processor).</p></li></ul> <p class="para"><span class="fixed">long long</span> </p> <ul class="simple-list"><li class="first-listitem"> <p class="first-para">A <span class="fixed">long long</span> is an integer number that's larger than a <span class="fixed">long</span> (8 bytes on an x86 processor).</p></li></ul> <p class="para"><span class="fixed">short</span> </p> <ul class="simple-list"><li class="first-listitem"> <p class="first-para">A short is an integer number that's shorter than an <span class="fixed">int</span> (2 bytes on an x86 processor).</p></li></ul> <p class="para"><span class="fixed">char</span> </p> <ul class="simple-list"><li class="first-listitem"> <p class="first-para">A <span class="fixed">char</span> 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.</p></li></ul><a name="223"></a><a name="IDX-139"></a> <p class="para"><span class="fixed">float</span> </p> <ul class="simple-list"><li class="first-listitem"> <p class="first-para">A <span class="fixed">float</span> is a floating-point number (4 bytes on an x86 processor). Floating-point numbers will be explained in more depth in the Section called <i class="emphasis">Floating-point Numbers</i> in <span class="chapterjump">Chapter 10</span>.</p></li></ul> <p class="para"><span class="fixed">.double</span> </p> <ul class="simple-list"><li class="first-listitem"> <p class="first-para">A <span class="fixed">double</span> is a floating-point number that is larger than a float (8 bytes on an x86 processor).</p></li></ul> <p class="para"><span class="fixed">unsigned</span> </p> <ul class="simple-list"><li class="first-listitem"> <p class="first-para"><span class="fixed">unsigned</span> 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 <span class="chapterjump">Chapter 10</span>.</p></li></ul> <p class="para"><span class="fixed">*</span> </p> <ul class="simple-list"><li class="first-listitem"> <p class="first-para">An asterisk (<span class="fixed">*</span>) 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 <span class="fixed">my_location</span> you have the number 20 stored. If the prototype said to pass an <span class="fixed">int</span>, you would use direct addressing mode and do <span class="fixed">pushl my_location</span>. However, if the prototype said to pass an <span class="fixed">int *</span>, you would do <span class="fixed">pushl $my_location</span> - 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.</p></li></ul> <p class="para"><span class="fixed">struct</span> </p> <ul class="simple-list"><li class="first-listitem"> <p class="first-para">A <span class="fixed">struct</span> is a set of data items that have been put together under a name. For example you could declare:</p> <div class="informalexample"><pre class="literallayout">struct teststruct {<br />int a;<a name="224"></a><a name="IDX-140"></a><br />char *b;<br />};<br /></pre></div> <p class="last-para">and any time you ran into <span class="fixed">struct teststruct</span> 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.</p></li></ul> <p class="para"><span class="fixed">typedef</span> </p> <ul class="simple-list"><li class="first-listitem"> <p class="first-para">A <span class="fixed">typedef</span> basically allows you to rename a type. For example, I can do <span class="fixed">typedef int myowntype</span>; in a C program, and any time I typed <span class="fixed">myowntype</span>, it would be just as if I typed <span class="fixed">int</span>. 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, <span class="fixed">typedef</span>s are useful for giving types more meaningful and descriptive names.</p> <p class="para"><b>Compatibility Note:</b> 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.</p></li></ul> <p class="last-para">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 <span class="fixed">/usr/lib</span> or <span class="fixed">/lib</span>. If you want to just see what symbols they define, just run <span class="fixed">objdump -R FILENAME</span> where <span class="fixed">FILENAME</span> 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 <a name="225"></a><a name="IDX-141"></a>GNU project also have info pages on them, which are a little more thorough than man pages.</p></div> <div class="footnotes"> <div class="footnote"> <p><sup>[<a href="http://www2.blogger.com/post-edit.g?blogID=8901974503278002812&postID=2114339705057527230#N148" name="ftn.N148">2</a>]</sup>The reason that parameters are pushed in the reverse order is because of functions which take a variable number of parameters like <span class="fixed">printf</span>. 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, <span class="fixed">printf</span> 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.</p><div class="chapter"><a name="ch08"></a> <div class="section"> <h2 class="first-section-title"><a name="226"></a><a name="ch08lev1sec4"></a>Useful Functions</h2> <p class="first-para">Several useful functions you will want to be aware of from the c library include:</p> <ul class="itemizedlist"><li class="first-listitem"> <p class="first-para"><span class="fixed">size_t strlen (const char *s)</span> calculates the size of null-terminated strings.</p> </li><li class="listitem"> <p class="first-para"><span class="fixed">int strcmp (const char *sl, const char *s2)</span> compares two strings alphabetically.</p> </li><li class="listitem"> <p class="first-para"><span class="fixed">char * strdup (const char *s)</span> takes the pointer to a string, and creates a new copy in a new location, and returns the new location.</p> </li><li class="listitem"> <p class="first-para"><span class="fixed">FILE * fopen (const char *filename, const char *opentype)</span> opens a managed, buffered file (allows easier reading and writing than using file descriptors directly).<sup>[<a href="http://www2.blogger.com/post-edit.g?blogID=8901974503278002812&postID=2114339705057527230#ftn.N42" name="N42">3</a>]</sup>, <sup>[<a href="http://www2.blogger.com/post-edit.g?blogID=8901974503278002812&postID=2114339705057527230#ftn.N59" name="N59">4</a>]</sup> </p> </li><li class="listitem"> <p class="first-para"><span class="fixed">int fclose (FILE * stream)</span> closes a file opened with <span class="fixed">fopen</span>.</p> </li><li class="listitem"> <p class="first-para"><span class="fixed">char * fgets (char *s, int count, FILE *stream)</span> fetches a line of characters into string <span class="fixed">s</span>.</p> </li><li class="listitem"> <p class="first-para"><span class="fixed">int fputs (const char *s, FILE *stream)</span> writes a string to the given open file.</p> </li><li class="listitem"> <p class="first-para"><span class="fixed">int fprintf (FILE *stream, const char *template, ...)</span> is just like <span class="fixed">printf</span>, but it uses an open file rather than defaulting to using standard output.</p></li></ul><a name="227"></a><a name="IDX-142"></a> <p class="last-para">You can find the complete manual on this library by going to <a class="url" href="http://www.gnu.org/software/libc/manual/" target="_top">http://www.gnu.org/software/libc/manual/</a> </p></div> <div class="footnotes"> <div class="footnote"> <p><sup>[<a href="http://www2.blogger.com/post-edit.g?blogID=8901974503278002812&postID=2114339705057527230#N42" name="ftn.N42">3</a>]</sup><span class="fixed">stdin</span>, <span class="fixed">stdout</span>, and <span class="fixed">stderr</span> (all lower case) can be used in these programs to refer to the files of their corresponding file descriptors.</p></div> <div class="footnote"> <p><sup>[<a href="http://www2.blogger.com/post-edit.g?blogID=8901974503278002812&postID=2114339705057527230#N59" name="ftn.N59">4</a>]</sup><span class="fixed">FILE</span> 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.</p><div class="chapter"><a name="ch08"></a> <div class="section"> <h2 class="first-section-title"><a name="228"></a><a name="ch08lev1sec5"></a>Building a Dynamic Library</h2> <p class="first-para">Let's say that we wanted to take all of our shared code from <span class="chapterjump">Chapter 6</span> and build it into a dynamic library to use in our programs. The first thing we would do is assemble them like normal:</p> <div class="informalexample"><pre class="literallayout">as write-record.s -o write-record.o<br />as read-record.s -o read-record.o<br /></pre></div> <p class="para">Now, instead of linking them into a program, we want to link them into a dynamic library. This changes our linker command to this:</p> <div class="informalexample"><pre class="literallayout">ld -shared write-record.o read-record.o -o librecord.so<br /></pre></div> <p class="para">This links both of these files together into a dynamic library called <span class="fixed">librecord.so</span>. 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.</p> <p class="para">Let's look at how we would link against this library. To link the <span class="fixed">write-records</span> program, we would do the following:</p> <div class="informalexample"><pre class="literallayout">as write-records.s -o write-records<br />ld -L . -dynamic-linker /lib/ld-linux.so.2 \<br /> -o write-records -lrecord write-records.o<br /></pre></div> <p class="para">In this command, <span class="fixed">-L .</span> told the linker to look for libraries in the current directory (it usually only searches <span class="fixed">/lib</span> directory, <span class="fixed">/usr/lib</span> directory, and a few others). As we've seen, the option <span class="fixed">-dynamic-linker /lib/ld-linux.so.2</span> specified the dynamic linker. The option <span class="fixed">-lrecord</span> tells the linker to search for functions in the file named <span class="fixed">librecord.so</span>.</p><a name="229"></a><a name="IDX-143"></a> <p class="para">Now the <span class="fixed">write-records</span> program is built, but it will not run. If we try it, we will get an error like the following:</p> <div class="informalexample"><pre class="literallayout">./write-records: error while loading shared libraries:<br />librecord.so: cannot open shared object file: No such<br />file or directory<br /></pre></div> <p class="para">This is because, by default, the dynamic linker only searches <span class="fixed">/lib</span>, <span class="fixed">/usr/lib</span>, and whatever directories are listed in <span class="fixed">/etc/ld.so.conf</span> 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:</p> <div class="informalexample"><pre class="literallayout">LD_LIBRARY_PATH=.<br />export LD_LIBRARY_PATH<br /></pre></div> <p class="para">Alternatively, if that gives you an error, do this instead:</p> <div class="informalexample"><pre class="literallayout">setenv LD_LIBRARY_PATH .<br /></pre></div> <p class="para">Now, you can run <span class="fixed">write-records</span> normally by typing <span class="fixed">./write-records</span>. Setting <span class="fixed">LD_LIBRARY_PATH</span> tells the linker to add whatever paths you give it to the library search path for dynamic libraries.</p> <p class="para">For further information about dynamic linking, see the following sources on the Internet:</p> <ul class="itemizedlist"><li class="first-listitem"> <p class="first-para">The man page for <span class="fixed">ld.so</span> contains a lot of information about how the Linux dynamic linker works.</p> </li><li class="listitem"> <p class="first-para"><a class="url" href="http://www.benyossef.com/presentations/dlink/" target="_top">http://www.benyossef.com/presentations/dlink/</a> is a great presentation on dynamic linking in Linux.</p> </li><li class="listitem"> <p class="first-para"><a class="url" href="http://www.linuxjournal.com/article.php?sid=1059" target="_top">http://www.linuxjournal.com/article.php?sid=1059</a> and <a class="url" href="http://www.linuxjournal.com/article.php?sid=1060" target="_top">http://www.linuxjournal.com/article.php?sid=1060</a> provide a good introduction <a name="230"></a><a name="IDX-144"></a>to the ELF file format, with more detail available at <a class="url" href="http://www.cs.ucdavis.edu/%7Ehaungs/paper/node10.html" target="_top">http://www.cs.ucdavis.edu/~haungs/paper/node10.html</a> </p> </li><li class="listitem"> <p class="first-para"><a class="url" href="http://www.iecc.com/linker/linker10.html" target="_top">http://www.iecc.com/linker/linker10.html</a> contains a great description of how dynamic linking works with ELF files.</p> </li><li class="listitem"> <p class="first-para"><a class="url" href="http://linux4u.jinr.ru/usoft/WWW/www_debian.org/Documentation/elf/node21.html" target="_top">http://linux4u.jinr.ru/usoft/WWW/www_debian.org/Documentation/elf/node21.html</a> contains a good introduction to programming position-independent code for shared libraries under Linux.</p></li></ul></div></div><br /><div class="section"> <h2 class="first-section-title"><a name="231"></a><a name="ch08lev1sec6"></a>Review</h2> <div class="section"> <h3 class="sect3-title"><a name="232"></a><a name="ch08lev2sec1"></a>Know the Concepts</h3> <ul class="itemizedlist"><li class="first-listitem"> <p class="first-para">What are the advantages and disadvantages of shared libraries?</p> </li><li class="listitem"> <p class="first-para">Given a library named 'foo', what would the library's filename be?</p> </li><li class="listitem"> <p class="first-para">What does the <span class="fixed">ldd</span> command do?</p> </li><li class="listitem"> <p class="first-para">Let's say we had the files <span class="fixed">foo.o</span> and <span class="fixed">bar.o</span>, 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?</p> </li><li class="listitem"> <p class="first-para">What is <i class="emphasis">typedef</i> for?</p> </li><li class="listitem"> <p class="first-para">What are <i class="emphasis">structs</i> for?</p> </li><li class="listitem"> <p class="first-para">What is the difference between a data element of type <i class="emphasis">int</i> and <i class="emphasis">int</i> *? How would you access them differently in your program?</p> </li><li class="listitem"> <p class="first-para">If you had a object file called <span class="fixed">foo.o</span>, what would be the command to create a shared library called 'bar'?</p> </li><li class="listitem"> <p class="first-para">What is the purpose of LD_LIBRARY_PATH?</p></li></ul><a name="233"></a><a name="IDX-145"></a></div> <div class="section"> <h3 class="sect3-title"><a name="234"></a><a name="ch08lev2sec2"></a>Use the Concepts</h3> <ul class="itemizedlist"><li class="first-listitem"> <p class="first-para">Rewrite one or more of the programs from the previous chapters to print their results to the screen using <span class="fixed">printf</span> rather than returning the result as the exit status code. Also, make the exit status code be 0.</p> </li><li class="listitem"> <p class="first-para">Use the <span class="fixed">factorial</span> function you developed in the Section called <i class="emphasis">Recursive Functions</i> in <span class="chapterjump">Chapter 4</span> to make a shared library. Then re-write the main program so that it links with the library dynamically.</p> </li><li class="listitem"> <p class="first-para">Rewrite the program above so that it also links with the 'c' library. Use the 'c' library's <span class="fixed">printf</span> function to display the result of the <span class="fixed">factorial</span> call.</p> </li><li class="listitem"> <p class="first-para">Rewrite the <span class="fixed">toupper</span> program so that it uses the <span class="fixed">c</span> library functions for files rather than system calls.</p></li></ul></div> <div class="section"> <h3 class="sect3-title"><a name="235"></a><a name="ch08lev2sec3"></a>Going Further</h3> <ul class="itemizedlist"><li class="first-listitem"> <p class="first-para">Make a list of all the environment variables used by the GNU/Linux dynamic linker.</p> </li><li class="listitem"> <p class="first-para">Research the different types of executable file formats in use today and in the history of computing. Tell the strengths and weaknesses of each.</p> </li><li class="listitem"> <p class="first-para">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.</p> </li><li class="listitem"> <p class="first-para">Research the use of <span class="fixed">LD_PRELOAD</span>. What is it used for? Try building a shared library that contained the <span class="fixed">exit</span> function, and have it write a message to STDERR before exitting. Use <span class="fixed">LD_PRELOAD</span> and run various programs with it. What are the results?</p></li></ul><a name="236"></a><a name="IDX-146"></a></div></div></div></div></div></div></div></div></div></div></div><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8901974503278002812-2114339705057527230?l=programminggroundup.blogspot.com'/></div>Adminhttp://www.blogger.com/profile/13783659974416042562noreply@blogger.com0tag:blogger.com,1999:blog-8901974503278002812.post-63126574146199674382007-01-31T18:17:00.000-08:002007-01-31T20:18:38.328-08:00Chapter 7: Developing Robust Programs<div class="highlights"> <p class="first-para">This chapter deals with developing programs that are <i class="emphasis">robust.</i> 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.</p></div> <div class="section"> <h2 class="sect2-title"><a name="184"></a><a name="ch07lev1sec1"></a>Where Does the Time Go?</h2> <p class="first-para">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:</p> <ul class="itemizedlist"><li class="first-listitem"> <p class="first-para">Programmers don't always schedule time for meetings or other non-coding activities that make up every day.</p> </li><li class="listitem"> <p class="first-para">Programmers often underestimate feedback times (how long it takes to pass change requests and approvals back and forth) for projects.</p> </li><li class="listitem"> <p class="first-para">Programmers don't always understand the full scope of what they are producing.</p> </li><li class="listitem"> <p class="first-para">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.</p> </li><li class="listitem"> <p class="first-para">Programmers often underestimate the amount of time it takes to get a program fully robust.</p></li></ul> <p class="para">The last item is the one we are interested in here. <i class="emphasis">It takes a lot of time and effort to develop robust programs.</i> More so than people usually guess, including <a name="185"></a><a name="IDX-118"></a>experienced programmers. Programmers get so focused on simply solving the problem at hand that they fail to look at the possible side issues.</p> <p class="para">In the <span class="fixed">toupper</span> 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 <span class="fixed">%eax</span>, 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.</p> <p class="last-para">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.</p><div class="section"> <h2 class="first-section-title"><a name="186"></a><a name="ch07lev1sec2"></a>Some Tips for Developing Robust Programs</h2> <div class="section"> <h3 class="sect3-title"><a name="187"></a><a name="ch07lev2sec1"></a>User Testing</h3> <p class="first-para">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 <a name="188"></a><a name="IDX-119"></a>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.</p> <p class="para">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.</p> <p class="last-para">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.</p></div> <div class="section"> <h3 class="sect3-title"><a name="189"></a><a name="ch07lev2sec2"></a>Data Testing</h3> <p class="first-para">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 <i class="emphasis">corner cases</i> or <i class="emphasis">edge cases.</i> Corner cases are the inputs that are most likely to cause problems or behave unexpectedly.</p> <p class="para">When testing numeric data, there are several corner cases you always need to test:</p> <ul class="itemizedlist"><li class="first-listitem"> <p class="first-para">The number 0</p> </li><li class="listitem"> <p class="first-para">The number 1</p><a name="190"></a><a name="IDX-120"></a> </li><li class="listitem"> <p class="first-para">A number within the expected range</p> </li><li class="listitem"> <p class="first-para">A number outside the expected range</p> </li><li class="listitem"> <p class="first-para">The first number in the expected range</p> </li><li class="listitem"> <p class="first-para">The last number in the expected range</p> </li><li class="listitem"> <p class="first-para">The first number below the expected range</p> </li><li class="listitem"> <p class="first-para">The first number above the expected range</p></li></ul> <p class="para">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.</p> <p class="last-para">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 <span class="fixed">assert</span> macro. You can simply put in your code <span class="fixed">assert (a > b);</span>, 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 <span class="fixed">assert</span> 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.</p></div> <div class="section"> <h3 class="sect3-title"><a name="191"></a><a name="ch07lev2sec3"></a>Module Testing</h3> <p class="first-para">Not only should you test your program as a whole, you need to test the individual <a name="192"></a><a name="IDX-121"></a>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.</p> <p class="para">In order to do this effectively, you have to develop functions whose sole purpose is to call functions for testing. These are called <i class="emphasis">drivers</i> (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.</p> <p class="last-para">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 <i class="emphasis">stub</i> which simply returns the values that function needs to proceed. For example, in an e-commerce application, I had a function called <span class="fixed">is_ready_to_checkout</span>. 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 <span class="fixed">is_ready_to_checkout</span> without the function being fully implemented.</p><div class="section"> <h2 class="first-section-title"><a name="193"></a><a name="ch07lev1sec3"></a>Handling Errors Effectively</h2> <p class="first-para">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.</p> <div class="section"> <h3 class="sect3-title"><a name="194"></a><a name="ch07lev2sec4"></a>Have an Error Code for Everything</h3> <p class="first-para">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.</p><a name="195"></a><a name="IDX-122"></a> <p class="para">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.</p> <p class="last-para">Error codes should also be accompanied by descriptive error messages. However, only in rare circumstances should the error message try to predict <i class="emphasis">why</i> 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.</p></div> <div class="section"> <h3 class="sect3-title"><a name="196"></a><a name="ch07lev2sec5"></a>Recovery Points</h3> <p class="first-para">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 <i class="emphasis">recovery point</i> 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.</p> <p class="para">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 <a name="197"></a><a name="IDX-123"></a>reports need exact error codes and messages.</p> <p class="para">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.</p> <p class="last-para">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.</p><div class="section"> <h2 class="first-section-title"><a name="198"></a><a name="ch07lev1sec4"></a>Making Our Program More Robust</h2> <p class="first-para">This section will go through making the <span class="fixed">add-year.s</span> program from <span class="chapterjump">Chapter 6</span> a little more robust.</p> <p class="para">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:</p> <div class="informalexample"><pre class="literallayout"> .include "linux.s"<br />.equ ST_ERROR_CODE, 8<br />.equ ST_ERROR_MSG, 12<br />.globl error_exit<br />.type error_exit, @function<br />error_exit:<br />pushl %ebp<br />movl %esp, %ebp<a name="199"></a><a name="IDX-124"></a><br />#Write out error code<br />movl ST_ERROR_CODE(%ebp), %ecx<br />pushl %ecx<br />call count_chars<br />popl %ecx<br />movl %eax, %edx<br />movl $STDERR, %ebx<br />movl $SYS_WRITE, %eax<br />int $LINUX_SYSCALL<br /><br />#Write out error message<br />movl ST_ERROR_MSG(%ebp), %ecx<br />pushl %ecx<br />call count_chars<br />popl %ecx<br />movl %eax, %edx<br />movl $STDERR, %ebx<br />movl $SYS_WRITE, %eax<br />int $LINUX_SYSCALL<br /><br />pushl $STDERR<br />call write_newline<br /><br />#Exit with status 1<br />movl $SYS_EXIT, %eax<br />movl $1, %ebx<br />int $LINUX_SYSCALL<br /></pre></div> <p class="para">Enter it in a file called <span class="fixed">error-exit.s</span>. 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.</p> <p class="para">Now let's look for potential error spots in our <span class="fixed">add-year</span> program. First of all, we don't check to see if either of our <span class="fixed">open</span> system calls actually complete properly.</p><a name="200"></a><a name="IDX-125"></a> <p class="para">Linux returns its status code in <span class="fixed">%eax</span>, so we need to check and see if there is an error.</p> <div class="informalexample"><pre class="literallayout"> #Open file for reading<br />movl $SYS_OPEN, %eax<br />movl $input_file_name, %ebx<br />movl $0, %ecx<br />movl $0666, %edx<br />int $LINUX_SYSCALL<br /><br />movl %eax, INPUT_DESCRIPTOR(%ebp)<br /><br />#This will test and see if %eax is<br />#negative. If it is not negative, it<br />#will jump to continue_processing.<br />#Otherwise it will handle the error<br />#condition that the negative number<br />#represents.<br />cmpl $0, %eax<br />jl continue_processing<br /><br /><br />#Send the error<br />.section .data<br />no_open_file_code:<br />.ascii "0001: \0"<br />no_open_file_msg:<br />.ascii "Can't Open Input File\0"<br /><br />.section .text<br />pushl $no_open_file_msg<br />pushl $no_open_file_code<br />call error_exit<br /><br />continue_processing:<a name="201"></a><a name="IDX-126"></a><br />#Rest of program<br /></pre></div> <p class="para">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.</p> <p class="para">After every system call, function call, or instruction which can have erroneous results you should add error checking and handling code.</p> <p class="para">To assemble and link the files, do:</p> <div class="informalexample"><pre class="literallayout">as add-year.s -o add-year.o<br />as error-exit.s -o error-exit.o<br />ld add-year.o write-newline.o error-exit.o read-record.o write-<br />record.o count-chars.o -o add-year<br /></pre></div> <p class="last-para">Now try to run it without the necessary files. It now exits cleanly and gracefully!</p><h2 class="first-section-title"><a name="202"></a><a name="ch07lev1sec5"></a>Review</h2> <div class="section"> <h3 class="sect3-title"><a name="203"></a><a name="ch07lev2sec6"></a>Know the Concepts</h3> <ul class="itemizedlist"><li class="first-listitem"> <p class="first-para">What are the reasons programmer's have trouble with scheduling?</p> </li><li class="listitem"> <p class="first-para">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.</p> </li><li class="listitem"> <p class="first-para">What are corner cases? Can you list examples of numeric corner cases?</p> </li><li class="listitem"> <p class="first-para">Why is user testing so important?</p> </li><li class="listitem"> <p class="first-para">What are stubs and drivers used for? What's the difference between the two?</p><a name="204"></a><a name="IDX-127"></a> </li><li class="listitem"> <p class="first-para">What are recovery points used for?</p> </li><li class="listitem"> <p class="first-para">How many different error codes should a program have?</p></li></ul></div> <div class="section"> <h3 class="sect3-title"><a name="205"></a><a name="ch07lev2sec7"></a>Use the Concepts</h3> <ul class="itemizedlist"><li class="first-listitem"> <p class="first-para">Go through the <span class="fixed">add-year.s</span> program and add error-checking code after every system call.</p> </li><li class="listitem"> <p class="first-para">Find one other program we have done so far, and add error-checking to that program.</p> </li><li class="listitem"> <p class="first-para">Add a recovery mechanism for <span class="fixed">add-year.s</span> that allows it to read from STDIN if it cannot open the standard file.</p></li></ul></div> <div class="section"> <h3 class="sect3-title"><a name="206"></a><a name="ch07lev2sec8"></a>Going Further</h3> <ul class="itemizedlist"><li class="first-listitem"> <p class="first-para">What, if anything, should you do if your error-reporting function fails? Why?</p> </li><li class="listitem"> <p class="first-para">Try to find bugs in at least one open-source program. File a bug report for it.</p> </li><li class="listitem"> <p class="first-para">Try to fix the bug you found in the previous exercise</p></li></ul></div></div></div></div></div></div></div><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8901974503278002812-6312657414619967438?l=programminggroundup.blogspot.com'/></div>Adminhttp://www.blogger.com/profile/13783659974416042562noreply@blogger.com0tag:blogger.com,1999:blog-8901974503278002812.post-56287921285725391342007-01-31T18:09:00.000-08:002007-01-31T20:17:29.468-08:00Chapter 6: Reading and Writing Simple Records<div class="section"> <h2 class="sect2-title"><a name="152"></a>Overview</h2><a name="153"></a><a name="IDX-95"></a> <p class="para">As mentioned in <span class="chapterjump">Chapter 5</span>, many applications deal with data that is <i class="emphasis">persistent -</i> 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 <span class="fixed">toupper</span> 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.</p> <p class="para">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.<sup>[<a href="http://www2.blogger.com/post-edit.g?blogID=8901974503278002812&postID=5628792128572539134#ftn.N34" name="N34">1</a>]</sup> </p> <div class="highlights"> <p class="first-para">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:</p> <ul class="itemizedlist"><li class="first-listitem"> <p class="first-para">Firstname - 40 bytes</p> </li><li class="listitem"> <p class="first-para">Lastname - 40 bytes</p> </li><li class="listitem"> <p class="first-para">Address - 240 bytes</p> </li><li class="listitem"> <p class="first-para">Age - 4 bytes</p></li></ul> <p class="para"><a name="154"></a><a name="IDX-96"></a>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).</p> <p class="para">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 <span class="fixed">record-def.s:</span> </p> <p class="para"> </p><div class="informalexample"><pre class="literallayout"> .equ RECORD_FIRSTNAME, 0<br />.equ RECORD_LASTNAME, 40<br />.equ RECORD_ADDRESS, 80<br />.equ RECORD_AGE, 320<br /><br />.equ RECORD_SIZE, 324<br /></pre></div> <p class="para">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 <span class="fixed">linux.s:</span> </p> <p class="para"> </p><div class="informalexample"><pre class="literallayout"> #Common Linux Definitions<br /><br />#System Call Numbers<br />.equ SYS_EXIT, 1<br />.equ SYS_READ, 3<br />.equ SYS_WRITE, 4<br />.equ SYS_OPEN, 5<br />.equ SYS_CLOSE, 6<br />.equ SYS_BRK, 45<a name="155"></a><a name="IDX-97"></a><br />#System Call Interrupt Number<br />.equ LINUX_SYSCALL, 0x80<br /><br />#Standard File Descriptors<br />.equ STDIN, 0<br />.equ STDOUT, 1<br />.equ STDERR, 2<br /><br />#Common Status Codes<br />.equ END_OF_FILE, 0<br /></pre></div> <p class="para">We will write three programs in this chapter using the structure defined in <span class="fixed">record-def.s.</span> 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.</p> <p class="para">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.</p> <p class="para">What parameters do these functions need in order to operate? We basically need:</p> <ul class="itemizedlist"><li class="first-listitem"> <p class="first-para">The location of a buffer that we can read a record into</p> </li><li class="listitem"> <p class="first-para">The file descriptor that we want to read from or write to</p></li></ul> <p class="para">Let's look at our reading function first:</p> <p class="para"> </p><div class="informalexample"><pre class="literallayout"> .include "record-def.s"<br />.include "linux.s"<br /><br />#PURPOSE: This function reads a record from the file<a name="156"></a><a name="IDX-98"></a><br /># descriptor<br />#<br />#INPUT: The file descriptor and a buffer<br />#<br />#OUTPUT: This function writes the data to the buffer<br /># and returns a status code.<br />#<br />#STACK LOCAL VARIABLES<br />.equ ST_READ_BUFFER, 8<br />.equ ST_FILEDES, 12<br />.section .text<br />.globl read_record<br />.type read_record, @function<br />read_record:<br />pushl %ebp<br />movl %esp, %ebp<br /><br />pushl %ebx<br />movl ST_FILEDES(%ebp), %ebx<br />movl ST_READ_BUFFER(%ebp), %ecx<br />movl $RECORD_SIZE, %edx<br />movl $SYS_READ, %eax<br />int $LINUX_SYSCALL<br /><br />#NOTE - %eax has the return value, which we will<br /># give back to our calling program<br />popl %ebx<br /><br />movl %ebp, %esp<br />popl %ebp<br />ret<br /></pre></div> <p class="para">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:</p> <p class="para"> </p><div class="informalexample"><a name="157"></a><a name="IDX-99"></a><pre class="literallayout"> .include "linux.s"<br />.include "record-def.s"<br />#PURPOSE: This function writes a record to<br /># the given file descriptor<br />#<br />#INPUT: The file descriptor and a buffer<br />#<br />#OUTPUT: This function produces a status code<br />#<br />#STACK LOCAL VARIABLES<br />.equ ST_WRITE_BUFFER, 8<br />.equ ST_FILEDES, 12<br />.section .text<br />.globl write_record<br />.type write_record, @function<br />write_record:<br />pushl %ebp<br />movl %esp, %ebp<br /><br />pushl %ebx<br />movl $SYS_WRITE, %eax<br />movl ST_FILEDES(%ebp), %ebx<br />movl ST_WRITE_BUFFER(%ebp), %ecx<br />movl $RECORD_SIZE, %edx<br />int $LINUX_SYSCALL<br /><br />#NOTE - %eax has the return value, which we will<br /># give back to our calling program<br />popl %ebx<br /><br />movl %ebp, %esp<br />popl %ebp<br />ret<br /><a name="158"></a><a name="IDX-100"></a><br /></pre></div> <p class="last-para">Now that we have our basic definitions down, we are ready to write our programs.</p></div></div> <div class="footnotes"> <div class="footnote"> <p><sup>[<a href="http://www2.blogger.com/post-edit.g?blogID=8901974503278002812&postID=5628792128572539134#N34" name="ftn.N34">1</a>]</sup>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.</p><h2 class="first-section-title"><a name="159"></a><a name="ch06lev1sec1"></a>Writing Records</h2> <p class="first-para">This program will simply write some hardcoded records to disk. It will:</p> <ul class="itemizedlist"><li class="first-listitem"> <p class="first-para">Open the file</p> </li><li class="listitem"> <p class="first-para">Write three records</p> </li><li class="listitem"> <p class="first-para">Close the file</p></li></ul> <p class="para">Type the following code into a file called <span class="fixed">write-records.s:</span> </p> <div class="informalexample"><pre class="literallayout"> .include "linux.s"<br />.include "record-def.s"<br /><br />.section .data<br /><br />#Constant data of the records we want to write<br />#Each text data item is padded to the proper<br />#length with null (i.e. 0) bytes.<br /><br />#.rept is used to pad each item. .rept tells<br />#the assembler to repeat the section between<br />#.rept and .endr the number of times specified.<br />#This is used in this program to add extra null<br />#characters at the end of each field to fill<br />#it up<br />record1:<br />.ascii "Fredrick\0"<br />.rept 31 #Padding to 40 bytes<br />.byte 0<br />.endr<br /><br />.ascii "Bartlett\0"<a name="160"></a><a name="IDX-101"></a><br />.rept 31 #Padding to 40 bytes<br />.byte 0<br />.endr<br /><br />.ascii "4242 S Prairie\nTulsa, OK 55555\0"<br />.rept 209 #Padding to 240 bytes<br />.byte 0<br />.endr<br /><br />.long 45<br /><br />record2:<br />.ascii "Marilyn\0"<br />.rept 32 #Padding to 40 bytes<br />.byte 0<br />.endr<br /><br />.ascii "Taylor\0"<br />.rept 33 #Padding to 40 bytes<br />.byte 0<br />.endr<br /><br />.ascii "2224 S Johannan St\nChicago, IL 12345\0"<br />.rept 203 #Padding to 240 bytes<br />.byte 0<br />.endr<br /><br />.long 29<br /><br />record3:<br />.ascii "Derrick\0"<br />.rept 32 #Padding to 40 bytes<br />.byte 0<br />.endr<a name="161"></a><a name="IDX-102"></a><br />.ascii "McIntire\0"<br />.rept 31 #Padding to 40 bytes<br />.byte 0<br />.endr<br /><br />.ascii "500 W Oakland\nSan Diego, CA 54321\0"<br />.rept 206 #Padding to 240 bytes<br />.byte 0<br />.endr<br /><br />.long 36<br /><br />#This is the name of the file we will write to<br />file_name:<br />.ascii "test.dat\0"<br /><br />.equ ST_FILE_DESCRIPTOR, -4<br />.globl _start<br />_start:<br />#Copy the stack pointer to %ebp<br />movl %esp, %ebp<br />#Allocate space to hold the file descriptor<br />subl $4, %esp<br /><br />#Open the file<br />movl $SYS_OPEN, %eax<br />movl $file_name, %ebx<br />movl $0101, %ecx #This says to create if it<br /> #doesn't exist, and open for<br /> #writing<br />movl $0666, %edx<br />int $LINUX_SYSCALL<br /><br />#Store the file descriptor away<br />movl %eax, ST_FILE_DESCRIPTOR(%ebp)<a name="162"></a><a name="IDX-103"></a><br />#Write the first record<br />pushl ST_FILE_DESCRIPTOR(%ebp)<br />pushl $recordl<br />call write_record<br />addl $8, %esp<br /><br />#Write the second record<br />pushl ST_FILE_DESCRIPTOR(%ebp)<br />pushl $record2<br />call write_record<br />addl $8, %esp<br /><br />#Write the third record<br />pushl ST_FILE_DESCRIPTOR(%ebp)<br />pushl $record3<br />call write_record<br />addl $8, %esp<br /><br />#Close the file descriptor<br />movl $SYS_CLOSE, %eax<br />movl ST_FILE_DESCRIPTOR(%ebp), %ebx<br />int $LINUX_SYSCALL<br /><br />#Exit the program<br />movl $SYS_EXIT, %eax<br />movl $0, %ebx<br />int $LINUX_SYSCALL<br /></pre></div> <p class="para">This is a fairly simple program. It merely consists of defining the data we want to write in the . <span class="fixed">data</span> 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 <span class="chapterjump">Appendix C</span>.</p><a name="163"></a><a name="IDX-104"></a> <p class="para">You may have noticed the lines:</p> <div class="informalexample"><pre class="literallayout"> .include "linux.s"<br />.include "record-def.s"<br /></pre></div> <p class="para">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 .<span class="fixed">globl</span>. However, constants defined in another file do need to be imported in this way.</p> <p class="para">Also, you may have noticed the use of a new assembler directive, .<span class="fixed">rept.</span> This directive repeats the contents of the file between the .<span class="fixed">rept</span> and the .<span class="fixed">endr</span> directives the number of times specified after .<span class="fixed">rept.</span> This is usually used the way we used it - to pad values in the . <span class="fixed">data</span> section. In our case, we are adding null characters to the end of each field until they are their defined lengths.</p> <p class="para">To build the application, run the commands:</p> <div class="informalexample"><pre class="literallayout">as write-records.s -o write-record.o<br />as write-record.s -o write-record.o<br />ld write-record.o write-records.o -o write-records<br /></pre></div> <p class="para">Here we are assembling two files separately, and then combining them together using the linker. To run the program, just type the following:</p> <div class="informalexample"><pre class="literallayout">./write-records<br /></pre></div> <p class="last-para">This will cause a file called <span class="fixed">test.dat</span> 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.</p><div class="section"> <h2 class="first-section-title"><a name="164"></a><a name="ch06lev1sec2"></a>Reading Records</h2><a name="165"></a><a name="IDX-105"></a> <p class="para">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.</p> <p class="para">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.<sup>[<a href="http://www2.blogger.com/post-edit.g?blogID=8901974503278002812&postID=5628792128572539134#ftn.N21" name="N21">2</a>]</sup> Note that this means our records must contain at least on