home *** CD-ROM | disk | FTP | other *** search
/ The Unsorted BBS Collection / thegreatunsorted.tar / thegreatunsorted / programming / asm_programming / CHAP4.DOC < prev    next >
Text File  |  1990-06-21  |  16KB  |  403 lines

  1.  
  2.  
  3.  
  4.                                                                             24
  5.  
  6.                                   CHAPTER 4 - SHOW_REGS
  7.  
  8.  
  9.              We got started using the program show_regs in the last chapter,
  10.              but we have already run into problems. The hex number doesn't
  11.              look the same once we put it in the register - that's because
  12.              what we are seeing in the arithmetic registers is an unsigned
  13.              number. Also, when we moved a byte from AL to CH, it was clear
  14.              that something had moved, but it wasn't clear what the number
  15.              was. There are two problems here:
  16.  
  17.                  (1) We want to use data in hex, binary, ascii, unsigned and
  18.                  signed format depending on what we are doing in the program.
  19.  
  20.                  (2) Some of the registers can be used as half registers, so
  21.                  we want a whole register when we need it and a half register
  22.                  when we need it.
  23.  
  24.              Nooooooo problem. There are eight registers whose formats we want
  25.              to be able to change: AX, BX, CX, DX, SI, DI, BP and SP. We need
  26.              to give each one a code to tell it what to display. The code is
  27.              the following:
  28.  
  29.                  signed number       1
  30.                  unsigned number     2
  31.                  binary number       3
  32.                  hex number          4
  33.                  ascii               5
  34.  
  35.              Also, we need to know whether AX, BX, CX and DX are half or full
  36.              registers. The code for that is:
  37.  
  38.                  half register       128       (80 hex)
  39.                  full register       0
  40.  
  41.              We will need to do two things - set up the codes, then tell
  42.              show_regs about the code. We'll begin by setting up the codes.
  43.  
  44.              First let's start with SI, DI, BP and SP. They must be full
  45.              registers, so the half register information is irrelevant.{1}  In
  46.              the data section is a set of data starting ax_byte, bx_byte ...
  47.              sp_byte. That is where you need to put the code. Don't change the
  48.              order of these variables. Just put the correct formatting code in
  49.              the appropriate byte. 
  50.  
  51.                  mov  si_byte, 3
  52.  
  53.              will display SI as a binary number. 
  54.  
  55.              ____________________
  56.  
  57.                 1 show_regs is very forgiving. It only recognizes half
  58.              registers where appropriate, and if you screw up on the format
  59.              code, it just makes it an unsigned number.
  60.  
  61.              ______________________
  62.  
  63.              The PC Assembler Tutor - Copyright (C) 1989 Chuck Nelson
  64.  
  65.  
  66.  
  67.  
  68.              Chapter 4 - SHOW_REGS                                          25
  69.              _____________________
  70.  
  71.                  mov  bp_byte, 4
  72.  
  73.              will display BP as a hex number.
  74.  
  75.                  mov  di_byte, 1
  76.  
  77.              will display DI as a signed number.
  78.  
  79.              That's pretty easy. If you are using AX, BX, CX, or DX as a full
  80.              register, they are exactly the same.
  81.  
  82.                  mov  dx_byte, 5     ; full register, character format
  83.                  mov  ax_byte, 2     ; full register, unsigned format
  84.                  mov  bx_byte, 3     ; full register, binary
  85.  
  86.              If we use half registers we need to pass more information.
  87.              show_regs needs to know that it is half registers, not full
  88.              registers; it also needs to know what the left format is and what
  89.              the right format is. This is easier than it sounds but will take
  90.              a little getting used to. The right nibble (half byte) gets the
  91.              right format and the left nibble (half byte) gets the left
  92.              format. Then you add 128 to the total. This works easily in hex.
  93.              13h means that the left half register is (1 = signed) and the
  94.              right register is (3 = binary). Then we add (128 = 80h) for a
  95.              total of 93h. Here are some more examples. Remember, 8 + 1 = 9, 8
  96.              + 2 = A, 8 + 3 = B, 8 + 4 = C, 8 + 5 = D
  97.  
  98.                  C4h       ; 80h + 44h  left and right are hex
  99.                  A5h       ; 80h + 25h  left is unsigned, right is ascii
  100.                  B1h       ; 80h + 31h  left is binary, right is signed
  101.                  D2h       ; 80h + 52h  left is ascii, right is unsigned
  102.                  94h       ; 80h + 14h  left is signed, right is hex
  103.  
  104.              There is a summary at the end of the chapter giving all the
  105.              commands and codes for show_regs. It is important to take some
  106.              time here and learn to make the registers look the way we want,
  107.              because later on we have machine instructions for signed numbers,
  108.              for ascii characters, for binary numbers, and you need to see
  109.              what the registers look like in the appropriate formats.
  110.              Spending a little time right now will save you a lot of time
  111.              later on.
  112.  
  113.              If you don't like using hex numbers you can use decimal numbers:
  114.  
  115.                  code = type_of_register + left code + right code
  116.  
  117.              where full register = 0, half register = 128d and:
  118.  
  119.                  NUMBER FORMAT        LEFT CODE     RIGHT CODE
  120.  
  121.                  signed                   16d            1d
  122.                  unsigned                 32d            2d
  123.                  binary                   48d            3d
  124.                  hex                      64d            4d
  125.                  ascii                    80d            5d
  126.  
  127.              Therefore, left binary, right hex = 128 + 48 + 4 = 180d. Some
  128.  
  129.  
  130.  
  131.  
  132.              The PC Assembler Tutor                                         26
  133.              ______________________
  134.  
  135.              more examples:
  136.  
  137.                  left ascii, right signed = 128 + 80 + 1 = 209d
  138.                  left signed, right binary = 128 + 16 + 3 = 147d
  139.                  left hex, right unsigned = 128 + 64 + 2 = 192d
  140.  
  141.              We can put in the code the same way as before.
  142.  
  143.                  mov  ax_byte, 192d
  144.                  mov  dx_byte, 147d
  145.                  mov  cx_byte, 0D2h
  146.                  mov  bx_byte, 94h
  147.  
  148.              We now have the codes in out program, but show_regs doesn't know
  149.              about them. In order to give the information to show_regs, we
  150.              call set_reg_style. set_reg_style makes a copy of your
  151.              information for use by show_regs. The next time that you call
  152.              show_regs, it will use the new register formats. There is a small
  153.              problem, however. The information we have is eight bytes long,
  154.              and ax is only two bytes long. How do we pass the information?
  155.              The answer is: we don't pass the information. Instead, we pass
  156.              the address of the information. If you look in the data segment
  157.              of temp2.asm, you will see that ax_byte is the first byte of this
  158.              data. We pass the address of ax_byte (the first byte) and
  159.              set_reg_style knows that that address plus the following 7
  160.              addresses have the information that it needs. There is a special
  161.              machine instruction for putting an address in a register - it is
  162.              LEA or load effective address. It looks like this:
  163.  
  164.                  lea  ax, ax_byte
  165.  
  166.              This instruction says: put the address of ax_byte in the AX
  167.              register. Combined with the call, we have:
  168.  
  169.                  lea  ax, ax_byte
  170.                  call set_reg_style
  171.  
  172.  
  173.              Before we start writing programs with set_reg_style, we will run
  174.              a pre-existing program called SETREGS.EXE. Its pathname is
  175.              \ASMHELP\SETREGS.EXE. It puts the same (pseudo) random number in
  176.              all arithmetic registers except SP, then requests a formatting
  177.              code for each register. After cycling through all the registers,
  178.              it asks you to press ENTER. It then puts a new random number in
  179.              the registers and starts the cycle again. The hex codes are
  180.              displayed on the screen before each request. As usual, use
  181.              Control-C to exit the program.
  182.  
  183.              Here is what the screen might look like after the first cycle.
  184.              The prseudo random number 2571 will be the same, but your
  185.              formatting might be different:
  186.  
  187.  
  188.  
  189.  
  190.  
  191.  
  192.  
  193.  
  194.  
  195.  
  196.              Chapter 4 - SHOW_REGS                                          27
  197.              _____________________
  198.  
  199.              *********************** SCREEN SHOT ***************************
  200.                  AX +02571                             SI +02571
  201.                  BH  00001010      BL  0B **           DI  02571
  202.                  CX  0A 0B **                          BP  0000101000001011
  203.                  DH  0A **         DL  0B **           SP  00C4H
  204.  
  205.                  CS  0AA4H   DS  0A42H   ES  0A25H   SS  0A35H   IP  0115H
  206.  
  207.                  OF   DF  IEF   TF   SF   ZF   AF   PF   CF
  208.                   x    +    x         +              O    x      COUNT  00009
  209.              ----------------------------------------------------------------
  210.              hex = C0h or 4h;   ascii = D0h or 5h
  211.              Enter a code for sp.
  212.              Enter a one byte hex number  4
  213.              Press ENTER to continue
  214.  
  215.              *****************************************************************
  216.  
  217.              The formats I have used are:
  218.                  AX   full register  (signed)
  219.                  BX   half registers (binary, ascii)
  220.                  CX   full register  (ascii)
  221.                  DX   half registers (ascii, ascii)
  222.                  SI   full register  (signed)
  223.                  DI   full register  (unsigned)
  224.                  BP   full register  (binary)
  225.                  SP   full register  (hex) 
  226.  
  227.              Cycle through the registers a couple of times. If you make them
  228.              binary, they get longer, if you make them hex or ascii they get
  229.              shorter; a sign appears if they are signed, and you can change
  230.              from full to half registers for AX, BX, CX and DX.
  231.  
  232.              You will always be able to tell what kind of number show_regs is
  233.              printing because (1) a signed number always has a + or - in front
  234.              of it, (2) a hex number always has an h after it, (3) a binary
  235.              number is 8 digits long for a half register or 16 digits long for
  236.              a full register, and (4) an ascii has an asterisk after it. Just
  237.              as with print_num, if the ascii character has one of the values
  238.              0-32, 127 or 255, it will print a hex number and show a double
  239.              asterisk '**' to signal the event. (5) If none of the above is
  240.              true, then it is an unsigned decimal number.
  241.  
  242.              If you have a feel for what's happening, it is time to take a
  243.              mini-test. This is an untimed test, so just make sure that it is
  244.              correct. I'll give you a particular style, and you figure out the
  245.              code for that style. The answers are at the bottom of the page.
  246.              You don't have to memorize the codes. You should be using the
  247.              summary at the end of the chapter for this quiz.
  248.  
  249.                  1.   full register, binary
  250.                  2.   half register, left ascii, right hex
  251.                  3.   half register, left signed, right unsigned
  252.                  4.   full register, ascii
  253.                  5.   half register, left binary, right ascii
  254.                  6.   half register, left hex, right signed
  255.                  7.   half register, left unsigned, right binary
  256.  
  257.  
  258.  
  259.  
  260.              The PC Assembler Tutor                                         28
  261.              ______________________
  262.  
  263.                  8.   full register, hex
  264.                  9.   full register, signed
  265.                  10.  half register, left signed, right binary.
  266.  
  267.              If you feel comfortable with what's going on and are able to do
  268.              set the registers with the help of the summary, we are ready to
  269.              move on. 
  270.  
  271.              Here are the answers.{2}
  272.  
  273.  
  274.  
  275.  
  276.  
  277.  
  278.  
  279.  
  280.  
  281.  
  282.  
  283.  
  284.  
  285.  
  286.  
  287.  
  288.  
  289.  
  290.  
  291.  
  292.  
  293.  
  294.  
  295.  
  296.  
  297.  
  298.  
  299.  
  300.  
  301.              ____________________
  302.  
  303.                 2 Here are the answers, both in hex and decimal.
  304.  
  305.                    PROBLEM      HEX       DECIMAL
  306.  
  307.                       1.         3h         3d
  308.                       2.        D4h       212d
  309.                       3.        92h       146d
  310.                       4.         5h         5d
  311.                       5.        B5h       181d
  312.                       6.        C1h       193d
  313.                       7.        A3h       163d
  314.                       8.         4h         4d
  315.                       9.         1h         1d
  316.                       10.       93h       147d
  317.  
  318.              These things are slow to calculate. It took me about a minute per
  319.              problem to do both the hex and binary.
  320.  
  321.  
  322.  
  323.  
  324.              Chapter 4 - SHOW_REGS                                          29
  325.              _____________________
  326.  
  327.  
  328.                                           SUMMARY
  329.  
  330.              The registers may be displayed in signed, unsigned, binary, hex,
  331.              and ascii formats.  The basic codes for this are:
  332.  
  333.                  signed    1
  334.                  unsigned  2
  335.                  binary    3
  336.                  hex       4
  337.                  ascii     5
  338.  
  339.              In addition you need to add the register type. They are:
  340.  
  341.                  full register  0
  342.                  half register  128d or 80h
  343.  
  344.  
  345.              For the left half register, we have:
  346.  
  347.                  FORMAT            LEFT HEX     LEFT DECIMAL
  348.  
  349.                  signed               10h           16d
  350.                  unsigned             20h           32d
  351.                  binary               30h           48d
  352.                  hex                  40h           64d
  353.                  ascii                50h           80d
  354.  
  355.  
  356.              Since the left code is of interest only when the half register
  357.              type is being used, we simply add 80h and come up with:
  358.  
  359.                  FORMAT            LEFT CODE    RIGHT CODE
  360.  
  361.                  signed                90h          1h
  362.                  unsigned              A0h          2h
  363.                  binary                B0h          3h
  364.                  hex                   C0h          4h
  365.                  ascii                 D0h          5h
  366.  
  367.  
  368.              Or we add 128d and have:
  369.  
  370.                  FORMAT            LEFT CODE    RIGHT CODE
  371.  
  372.                  signed              144d           1d
  373.                  unsigned            160d           2d
  374.                  binary              176d           3d
  375.                  hex                 192d           4d
  376.                  ascii               208d           5d
  377.  
  378.  
  379.              SETTING THE FORMATS
  380.  
  381.              Formats are set by calling set_reg_style. The address of ax_byte
  382.              must be in AX. The standard assembler instructions for this are:
  383.  
  384.  
  385.  
  386.  
  387.  
  388.              The PC Assembler Tutor                                         30
  389.              ______________________
  390.  
  391.                  lea  ax, ax_byte
  392.                  call set_reg_style
  393.  
  394.              set_reg_style makes a copy of your format data. It changes
  395.              nothing on the screen. The next time that you call show_regs, it
  396.              will use the new formatting data.
  397.  
  398.              The correct order for the data in the data segment is:
  399.  
  400.              ax_byte, bx_byte, cx_byte, dx_byte, si_byte, di_byte, bp_byte,
  401.              sp_byte. They are, of course, all byte sized data.
  402.  
  403.