home *** CD-ROM | disk | FTP | other *** search
/ Hall of Fame / HallofFameCDROM.cdr / prog4 / assm.lzh / ASMTUTR1.DOC < prev    next >
Text File  |  1983-12-11  |  24KB  |  415 lines

  1.  
  2.  
  3.  
  4.                     IBM Personal Computer Assembly
  5.                          Language Tutorial
  6.  
  7.                           Joshua Auerbach
  8.                           Yale University
  9.                         Yale Computer Center
  10.                          175 Whitney Avenue
  11.                            P. O. Box 2112
  12.                      New Haven, Connecticut 06520
  13.                          Installation Code YU
  14.                  Integrated Personal Computers Project
  15.                         Communications Group
  16.                  Communications and Data Base Division
  17.                             Session C316
  18.  
  19.  
  20. This talk is for people who are just getting started with the PC MACRO
  21. Assembler.  Maybe you are just contemplating doing some coding in
  22. assembler, maybe you have tried it with mixed success.  If you are here to
  23. get aimed in the right direction, to get off to a good start with the
  24. assembler, then you have come for the right reason.  I can't promise you'll
  25. get what you want, but I'll do my best.
  26. On the other hand, if you have already turned out some working assembler
  27. code, then this talk is likely to be on the elementary side for you.  If
  28. you want to review a few basics and have no where else pressing to go, then
  29. by all means stay.
  30.  
  31. Why Learn Assembler?
  32. ____________________
  33. Why Learn Assembler?
  34. Why Learn Assembler?
  35. Why Learn Assembler?
  36. The reasons for LEARNING assembler are not the same as the reasons for
  37. USING it in a particular application.  But, we have to start with some of
  38. the reasons for using it and then I think the reasons for learning it will
  39. become clear.
  40. First, let's dispose of a bad reason for using it.  Don't use it just
  41. because you think it is going to execute faster.  A particular sequence of
  42. ordinary bread-and-butter computations written in PASCAL, C, FORTRAN, or
  43. compiled BASIC can do the job just about as fast as the same algorithm
  44. coded in assembler.  Of course, interpretive BASIC is slower, but if you
  45. have a BASIC application which runs too slow you probably want to try com-
  46. IBM PC Assembly Language Tutorial                                         1
  47.  
  48.  
  49. piling it before you think too much about translating parts of it to
  50. another language.
  51. On the other hand, high level languages do tend to isolate you from the
  52. machine.  That is both their strength and their weakness.  Usually, when
  53. implemented on a micro, a high level language provides an escape mechanism
  54. to the underlying operating system or to the bare machine.  So, for
  55. example, BASIC has its PEEK and POKE.  But, the route to the bare machine
  56. is often a circuitous one, leading to tricky programming which is hard to
  57. follow.
  58. For those of us working on PC's connected to SHARE-class mainframes, we are
  59. generally concerned with three interfaces:  the keyboard, the screen, and
  60. the communication line or lines.  All three of these entities raise machine
  61. dependent issues which are imperfectly addressed by the underlying operat-
  62. ing system or by high level languages.
  63. Sometimes, the system or the language does too little for you.  For
  64. example, with the asynch adapter, the system provides no interrupt handler,
  65. no buffer, and no flow control.  The application is stuck with the respon-
  66. sibility for monitoring that port and not missing any characters, then
  67. deciding what to do with all errors.  BASIC does a reasonable job on some
  68. of this, but that is only BASIC.  Most other languages do less.
  69. Sometimes, the system may do too much for you.  System support for the key-
  70. board is an example.  At the hardware level, all 83 keys on the keyboard
  71. send unique codes when they are pressed, held down, and released.  But,
  72. someone has decided that certain keys, like Num Lock and Scroll Lock are
  73. going to do certain things before the application even sees them and can't
  74. therefore be used as ordinary keys.
  75. Sometimes, the system does about the right amount of stuff but does it less
  76. efficiently then it should.  System support for the screen is in this
  77. class.  If you use only the official interface to the screen you sometimes
  78. slow your application down unacceptably.  I said before, don't use assem-
  79. bler just to speed things up, but there I was talking about mainline code,
  80. which generally can't be speeded up much by assembler coding.  A critical
  81. system interface is a different matter:  sometimes we may have to use
  82. assembler to bypass a hopelessly inefficient implementation.  We don't want
  83. to do this if we can avoid it, but sometimes we can't.
  84. Assembly language code can overcome these deficiencies.  In some cases, you
  85. can also overcome these deficiencies by judicious use of the escape valves
  86. which your high level language provides.  In BASIC, you can PEEK and POKE
  87. and INP and OUT your way around a great many issues.  In many other lan-
  88. guages you can issue system calls and interrupts and usually manage, one
  89. way or other, to modify system memory.  Writing handlers to take real-time
  90. hardware interrupts from the keyboard or asynch port, though, is still
  91. going to be a problem in most languages.  Some languages claim to let you
  92. do it but I have yet to see an acceptably clean implementation done that
  93. way.
  94. The real reason while assembler is better than "tricky POKEs" for writing
  95. machine-dependent code, though, is the same reason why PASCAL is better
  96. than assembler for writing a payroll package:  it is easier to maintain.
  97. IBM PC Assembly Language Tutorial                                         2
  98.  
  99.  
  100. Let the high level language do what it does best, but recognize that there
  101. are some things which are best done in assembler code.  The assembler,
  102. unlike the tricky POKE, can make judicious use of equates, macros, labels,
  103. and appropriately placed comments to show what is really going on in this
  104. machine-dependent realm where it thrives.
  105. So, there are times when it becomes appropriate to write in assembler; giv-
  106. en that, if you are a responsible programmer or manager, you will want to
  107. be "assembler-literate" so you can decide when assembler code should be
  108. written.
  109. What do I mean by "assembler-literate?"  I don't just mean understanding
  110. the 8086 architecture; I think, even if you don't write much assembler code
  111. yourself, you ought to understand the actual process of turning out assem-
  112. bler code and the various ways to incorporate it into an application.  You
  113. ought to be able to tell good assembler code from bad, and appropriate
  114. assembler code from inappropriate.
  115.  
  116. Steps to becoming ASSEMBLER-LITERATE
  117. ____________________________________
  118. Steps to becoming ASSEMBLER-LITERATE
  119. Steps to becoming ASSEMBLER-LITERATE
  120. Steps to becoming ASSEMBLER-LITERATE
  121. 1.  Learn the 8086 architecture and most of the instruction set.  Learn
  122.     what you need to know and ignore what you don't.  Reading:  The 8086
  123.     Primer by Stephen Morse, published by Hayden.  You need to read only
  124.     two chapters, the one on machine organization and the one on the
  125.     instruction set.
  126. 2.  Learn about a few simple DOS function calls.  Know what services the
  127.     operating system provides.  If appropriate, learn a little about other
  128.     systems too.  It will aid portability later on.  Reading:  appendices D
  129.     and E of the PC DOS manual.
  130. 3.  Learn enough about the MACRO assembler and the LINKer to write some
  131.     simple things that really work.  Here, too, the main thing is figuring
  132.     out what you don't need to know.  Whatever you do, don't study the sam-
  133.     ple programs distributed with the assembler unless you have nothing
  134.     better!
  135. 4.  At the same time as you are learning the assembler itself, you will
  136.     need to learn a few tools and concepts to properly combine your assem-
  137.     bler code with the other things you do.  If you plan to call assembler
  138.     subroutines from a high level language, you will need to study the
  139.     interface notes provided in your language manual.  Usually, this forms
  140.     an appendix of some sort.  If you plan to package your assembler rou-
  141.     tines as .COM programs you will need to learn to do this.  You should
  142.     also learn to use DEBUG.
  143. 5.  Read the Technical Reference, but very selectively.  The most important
  144.     things to know are the header comments in the BIOS listing.  Next, you
  145.     will want to learn about the RS 232 port and maybe about the video
  146.     adapters.
  147.  
  148. IBM PC Assembly Language Tutorial                                         3
  149.  
  150.  
  151. Notice that the key thing in all five phases is being selective.  It is
  152. easy to conclude that there is too much to learn unless you can throw away
  153. what you don't need.  Most of the rest of this talk is going to deal with
  154. this very important question of what you need and don't need to learn in
  155. each phase.  In some cases, I will have to leave you to do almost all of
  156. the learning, in others, I will teach a few salient points, enough, I hope,
  157. to get you started.  I hope you understand that all I can do in an hour is
  158. get you started on the way.
  159.  
  160. Phase 1:  Learn the architecture and instruction set
  161. ____________________________________________________
  162. Phase 1:  Learn the architecture and instruction set
  163. Phase 1:  Learn the architecture and instruction set
  164. Phase 1:  Learn the architecture and instruction set
  165. The Morse book might seem like a lot of book to buy for just two really
  166. important chapters; other books devote a lot more space to the instruction
  167. set and give you a big beautiful reference page on each instruction.  And,
  168. some of the other things in the Morse book, although interesting, really
  169. aren't very vital and are covered too sketchily to be of any real help.
  170. The reason I like the Morse book is that you can just read it; it has a
  171. very conversational style, it is very lucid, it tells you what you really
  172. need to know, and a little bit more which is by way of background; because
  173. nothing really gets belabored to much, you can gracefully forget the things
  174. you don't use.  And, I very much recommend READING Morse rather than study-
  175. ing it.  Get the big picture at this point.
  176. Now, you want to concentrate on those things which are worth fixing in mem-
  177. ory.  After you read Morse, you should relate what you have learned to this
  178. outline.
  179. 1.  You want to fix in your mind the idea of the four segment registers
  180.     CODE, DATA, STACK, and EXTRA.  This part is pretty easy to grasp.  The
  181.     8086 and the 8088 use 20 bit addresses for memory, meaning that they
  182.     can address up to 1 megabyte of memory.  But, the registers and the
  183.     address fields in all the instructions are no more that 16 bits long.
  184.     So, how to address all of that memory?  Their solution is to put
  185.     together two 16 bit quantities like this:
  186.       calculation  SSSS0   ---- value in the relevant segment register SHL 4
  187.       depicted in   AAAA   ---- apparent address from register or instruction
  188.       hexadecimal --------
  189.                    RRRRR   ---- real address placed on address bus
  190.     In other words, any time memory is accessed, your program will supply a
  191.     sixteen bit address.  Another sixteen bit address is acquired from a
  192.     segment register, left shifted four bits (one nibble) and added to it
  193.     to form the real address.  You can control the values in the segment
  194.     registers and thus access any part of memory you want.  But the segment
  195.     registers are specialized:  one for code, one for most data accesses,
  196.     one for the stack (which we'll mention again) and one "extra" one for
  197.     additional data accesses.
  198.     Most people, when they first learn about this addressing scheme become
  199.     obsessed with converting everything to real 20 bit addresses.  After a
  200.     while, though, you get use to thinking in segment/offset form.  You
  201. IBM PC Assembly Language Tutorial                                         4
  202.  
  203.  
  204.     tend to get your segment registers set up at the beginning of the pro-
  205.     gram, change them as little as possible, and think just in terms of
  206.     symbolic locations in your program, as with any assembly language.
  207.       EXAMPLE:
  208.            MOV  AX,DATASEG
  209.            MOV  DS,AX          ;Set value of Data segment
  210.            ASSUME DS:DATASEG   ;Tell assembler DS is usable
  211.            .......
  212.            MOV  AX,PLACE       ;Access storage symbolically by 16 bit address
  213.     In the above example, the assembler knows that no special issues are
  214.     involved because the machine generally uses the DS register to complete
  215.     a normal data reference.
  216.     If you had used ES instead of DS in the above example, the assembler
  217.     would have known what to do, also.  In front of the MOV instruction
  218.     which accessed the location PLACE, it would have placed the ES segment
  219.     prefix.  This would tell the machine that ES should be used, instead of
  220.     DS, to complete the address.
  221.     Some conventions make it especially easy to forget about segment regis-
  222.     ters.  For example, any program of the COM type gets control with all
  223.     four segment registers containing the same value.  This program exe-
  224.     cutes in a simplified 64K address space.  You can go outside this
  225.     address space if you want but you don't have to.
  226. 2.  You will want to learn what other registers are available and learn
  227.     their personalities:
  228.        AX and DX are general purpose registers.  They become special only
  229.         when accessing machine and system interfaces.
  230.        CX is a general purpose register which is slightly specialized for
  231.         counting.
  232.        BX is a general purpose register which is slightly specialized for
  233.         forming base-displacement addresses.
  234.        AX-DX can be divided in half, forming AH, AL, BH, BL, CH, CL, DH,
  235.         DL.
  236.        SI and DI are strictly 16 bit.  They can be used to form indexed
  237.         addresses (like BX) and they are also used to point to strings.
  238.        SP is hardly ever manipulated.  It is there to provide a stack.
  239.        BP is a manipulable cousin to SP.  Use it to access data which has
  240.         been pushed onto the stack.
  241.        Most sixteen bit operations are legal (even if unusual) when per-
  242.         formed in SI, DI, SP, or BP.
  243.  
  244.  
  245. IBM PC Assembly Language Tutorial                                         5
  246.  
  247.  
  248. 3.  You will want to learn the classifications of operations available
  249.     WITHOUT getting hung up in the details of how 8086 opcodes are con-
  250.     structed.
  251.     8086 opcodes are complex.  Fortunately, the assembler opcodes used to
  252.     assemble them are simple.  When you read a book like Morse, you will
  253.     learn some things which are worth knowing but NOT worth dwelling on.
  254.     a.  8086 and 8088 instructions can be broken up into subfields and bits
  255.         with names like R/M, MOD, S and W. These parts of the instruction
  256.         modify the basic operation in such ways as whether it is 8 bit or
  257.         16 bit, if 16 bit, whether all 16 bits of the data are given,
  258.         whether the instruction is register to register, register to
  259.         memory, or memory to register, for operands which are registers,
  260.         which register, for operands which are memory, what base and index
  261.         registers should be used in finding the data.
  262.     b.  Also, some instructions are actually represented by several differ-
  263.         ent machine opcodes depending on whether they deal with immediate
  264.         data or not, or on other issues, and there are some expedited forms
  265.         which assume that one of the arguments is the most commonly used
  266.         operand, like AX in the case of arithmetic.
  267.     There is no point in memorizing any of this detail; just distill the
  268.     bottom line, which is, what kinds of operand combinations EXIST in the
  269.     instruction set and what kinds don't.  If you ask the assembler to ADD
  270.     two things and the two things are things for which there is a legal ADD
  271.     instruction somewhere in the instruction set, the assembler will find
  272.     the right instruction and fill in all the modifier fields for you.
  273.     I guess if you memorized all the opcode construction rules you might
  274.     have a crack at being able to disassemble hex dumps by eye, like you
  275.     may have learned to do somewhat with 370 assembler.  I submit to you
  276.     that this feat, if ever mastered by anyone, would be in the same class
  277.     as playing the "Minute Waltz" in a minute; a curiosity only.
  278.     Here is the basic matrix you should remember:
  279.  
  280.  
  281.  
  282.  
  283.  
  284.  
  285.  
  286. IBM PC Assembly Language Tutorial                                         6
  287.  
  288.  
  289.          Two operands:          One operand:
  290.           R <-- M                R
  291.           M <-- R                M
  292.           R <-- R                S *
  293.           R|M <-- I
  294.           R|M <-- S  *
  295.           S <-- R|M  *
  296.       * -- data moving instructions (MOV, PUSH, POP) only
  297.       S -- segment register (CS, DS, ES, SS)
  298.       R -- ordinary register (AX, BX, CX, DX, SI, DI, BP, SP,
  299.                               AH, AL, BH, BL, CH, CL, DH, DL)
  300.       M -- one of the following
  301.                pure address
  302.                [BX]+offset
  303.                [BP]+offset
  304.                any of the above indexed by SI
  305.                any of the first three indexed by DI
  306. 4.  Of course, you want to learn the operations themselves.  As I've sug-
  307.     gested, you want to learn the op codes as the assembler presents them,
  308.     not as the CPU machine language presents them.  So, even though there
  309.     are many MOV op codes you don't need to learn them.  Basically, here is
  310.     the instruction set:
  311.     a.  Ordinary two operand instructions.  These instructions perform an
  312.         operation and leave the result in place of one of the operands.
  313.         They are
  314.         1)  ADD and ADC -- addition, with or without including a carry from
  315.             a previous addition
  316.         2)  SUB and SBB -- subtraction, with or without including a borrow
  317.             from a previous subtraction
  318.         3)  CMP -- compare.  It is useful to think of this as a subtraction
  319.             with the answer being thrown away and neither operand actually
  320.             changed
  321.         4)  AND, OR, XOR -- typical boolean operations
  322.         5)  TEST -- like an AND, except the answer is thrown away and nei-
  323.             ther operand is changed.
  324.         6)  MOV -- move data from source to target
  325.         7)  LDS, LES, LEA -- some specialized forms of MOV with side
  326.             effects
  327.     b.  Ordinary one operand instructions.  These can take any of the oper-
  328.         and forms described above.  Usually, the perform the operation and
  329.         leave the result in the stated place:
  330.         1)  INC -- increment contents
  331.  
  332. IBM PC Assembly Language Tutorial                                         7
  333.  
  334.  
  335.         2)  DEC -- decrement contents
  336.         3)  NEG -- twos complement
  337.         4)  NOT -- ones complement
  338.         5)  PUSH -- value goes on stack (operand location itself unchanged)
  339.         6)  POP -- value taken from stack, replaces current value
  340.     c.  Now you touch on some instructions which do not follow the general
  341.         operand rules but which require the use of certain registers.  The
  342.         important ones are
  343.         1)  The multiply and divide instructions
  344.         2)  The "adjust" instructions which help in performing arithmetic
  345.             on ASCII or packed decimal data
  346.         3)  The shift and rotate instructions.  These have a restriction on
  347.             the second operand:  it must either be the immediate value 1 or
  348.             the contents of the CL register.
  349.         4)  IN and OUT which send or receive data from one of the 1024
  350.             hardware ports.
  351.         5)  CBW and CWD -- convert byte to word or word to doubleword by
  352.             sign extension
  353.     d.  Flow of control instructions.  These deserve study in themselves
  354.         and we will discuss them a little more.  They include
  355.         1)  CALL, RET -- call and return
  356.         2)  INT, IRET -- interrupt and return-from-interrupt
  357.         3)  JMP -- jump or "branch"
  358.         4)  LOOP, LOOPNZ, LOOPZ -- special (and useful) instructions which
  359.             implement a counted loop similar to the 370 BCT instruction
  360.         5)  various conditional jump instructions
  361.     e.  String instructions.  These implement a limited storage-to-storage
  362.         instruction subset and are quite powerful.  All of them have the
  363.         property that
  364.         1)  The source of data is described by the combination DS and SI.
  365.         2)  The destination of data is described by the combination ES and
  366.             DI.
  367.         3)  As part of the operation, the SI and/or DI register(s) is(are)
  368.             incremented or decremented so the operation can be repeated.
  369.  
  370. IBM PC Assembly Language Tutorial                                         8
  371.  
  372.  
  373.         They include
  374.         1)  CMPSB/CMPSW -- compare byte or word
  375.         2)  LODSB/LODSW -- load byte or word into AL or AX
  376.         3)  STOSB/STOSW -- store byte or word from AL or AX
  377.         4)  MOVSB/MOVSW -- move byte or word
  378.         5)  SCASB/SCASW -- compare byte or word with contents of AL or AX
  379.         6)  REP/REPE/REPNE -- a prefix which can be combined with any of
  380.             the above instructions to make them execute repeatedly across a
  381.             string of data whose length is held in CX.
  382.     f.  Flag instructions: CLI, STI, CLD, STD, CLC, STC.  These can set or
  383.         clear the interrupt (enabled) direction (for string operations) or
  384.         carry flags.
  385.     The addressing summary and the instruction summary given above masks a
  386.     lot of annoying little exceptions.  For example, you can't POP CS, and
  387.     although the R <-- M form of LES is legal, the M <-- R form isn't etc.
  388.     etc.  My advice is
  389.     a.  Go for the general rules
  390.     b.  Don't try to memorize the exceptions
  391.     c.  Rely on common sense and the assembler to teach you about
  392.         exceptions over time.  A lot of the exceptions cover things you
  393.         wouldn't want to do anyway.
  394. 5.  A few instructions are rich enough and useful enough to warrent careful
  395.     study.  Here are a few final study guidelines:
  396.     a.  It is well worth the time learning to use the string instruction
  397.         set effectively.  Among the most useful are
  398.                 REP MOVSB           ;moves a string
  399.                 REP STOSB           ;initializes memory
  400.                 REPNE SCASB         ;look up occurance of character in string
  401.                 REPE CMPSB          ;compare two strings
  402.     b.  Similarly, if you have never written for a stack machine before,
  403.         you will need to exercise PUSH and POP and get very comfortable
  404.         with them because they are going to be good friends.  If you are
  405.         used to the 370, with lots of general purpose registers, you may
  406.         find yourself feeling cramped at first, with many fewer registers
  407.         and many instructions having register restrictions.  But, you have
  408.         a hidden ally:  you need a register and you don't want to throw
  409.         away what's in it?  Just PUSH it, and when you are done, POP it
  410.         back.  This can lead to abuse.  Never have more than two
  411.         "expedient" PUSHes in effect and never leave something PUSHed
  412.         across a major header comment or for more than 15 instructions or
  413. IBM PC Assembly Language Tutorial                                         9
  414.  
  415.