Course  
  Menu  
  Course  
 Description 
  Course  
  Outline  
 Assignments 
 & Doc Specs 
  Software  
  Summary  
  Class  
  Notes  
 Pseudocode 
  Modules  
  SIC/XE  
  Reference  
 Course  
 Supplement 
CNW Home
Fall Term, 2006  .

Assignment #5

Programming exercises: Due by noon on Friday, November 10, 2006.

In both pass 1 and pass 2, an assembler must keep track of a "location counter" that advances according to how many bytes each program statement consumes. Comments and directives other than storage directives consume 0 bytes. Instructions consume 1,2,3, or 4 bytes. The WORD directive consumes 3 bytes, but the other storage directives consume storage from 0 bytes on up. For this assignment, you are to devise C functions that return the location counter increment based on the information determined by your breakup routine. There are two basic cases:

  1. The opcode is not a storage directive
  2. The opcode is a storage directive
In part A of the assignment you are to devise an opcodeincr routine to deal with the first case and in part B you are to devise a storageincr routine to deal with the 2nd.

  1. opcodeincr specifications:
    Structures
    #ifndef SYMBSIZE
       #define SYMBSIZE 10
    #endif
    typedef struct tabinfo
      {
        int  val;
        int  type;
        int  info;
      } tabdata;
    typedef struct tablemem
      {
        char    symbol[SYMBSIZE];
        tabdata symbdata;
      } tabletype;
    extern tabletype codetable[];  // supplied by test driver program
    extern int codetabsize;        // supplied by test driver program
    int opcodeincr(tablindx, ni, xbpe)
    
    int tablindx, ni, xbpe;
    Parameters:
    1. tablindx is the index in codetable of an op code that is not a storage directive
    2. ni and xbpe provide the integer values of the "nixbpe" bits (compatible with breakup)
    Assumptions:

    You are to assume that breakup and findlast have been run to produce the parameters needed by opcodeincr (in particular, if findlast doesn't find the op code, or if it finds a storage directive, then opcodeincr won't get executed).

    You are to assume that you have an (externally defined) assembler code table structured in the same format as your symbol table (so your search routine (findlast) works for this table as well as your symbol table). Such a table is present in the course directory (/usr/public/cop3601/cwinton). For each entry in the table, the symbol portion gives the symbolic op code, the tabinfo portion gives the assembler code's numeric value, and the type portion gives the instruction type as follows:

     type description
    0RSUB
    1other 3/4 byte instructions
    22-byte instruction using 2 registers
    32-byte instruction using 1 register
    42-byte instruction using a register and a number
    5BYTE directive
    6WORD directive
    7RESB directive
    8RESW directive
    10,11START, END directives
    20,21BASE, NOBASE directives
    30LTORG directive
    40,41EXTDEF, EXTREF directives
    >=50other directives
    For instructions, the info portion gives the instruction length (2 or 3). The WORD storage directive has info value 3, as does RESW; for RESB the value is 1.

    Returned Value:

    Return the amount to increment the location counter by as follows:
    0 for assembler directive with e-bit = 0
    2 for 2-byte with e-bit of 0
    3 for 3-byte with e-bit of 0
    4 for 3-byte with e-bit = 1
    -1 for all other cases (error).
    File name:
    opcodeincr.c

    Procedure:

    • Design and construct an opcodeincr routine that conforms to the above specification. Note that the component values produced by breakup are not needed, since the codetable location of the opcode and the "nixbpe" values have the information needed to determine the increment amount.
    • The driver COP3601-5.o for this assignment is in the assgn-5 subdirectory of the class directory. It is for both part A and part B, providing the means for invoking and testing both your opcodeincr and storageincr routines in a manner analogous to the previous assignment. The driver also uses your findlast and breakup routines to control the test data that is input to your opcodeincr and storageincr routines. This also insures that all of your routines are working together effectively.
    • Devise a make file named <student-id>-5.makefile to compile your storageincr routine and link it with the supplied driver, executable named <student-id>-5. Since the makefile is to support both part A and part B, you may want to supply a stub for storageincr.c until you are ready to work on it. The basic command lines needed are:
      cc COP3601-5.o opcodeincr.o storageincr.o findlast.o breakup.o -o <student-id>-5
      cc -c opcodeincr.c -o opcodeincr.o
      cc -c storageincr.c -o storageincr.o
      The hlib.log functions are already linked in with COP3601-5.o.
    • Devise a test plan for your subroutine that uses the driver to fully exercise your subroutine and covers all cases outlined above.

      When you are satisfied that you have an effective test plan, remove hlib.log and then run your tests. When finished, move hlib.log to a file named <student-id>-5.A.log for use in your Part A documentation in a manner analogous to that for prior assignments.

      Examples:

      opcodeincr for "+LDA" should return 4
      opcodeincr for "+CLEAR" should return -1
      opcodeincr for "CLEAR" should return 2
      opcodeincr for "BASE" should return 0

  2. storageincr specifications:
    Structures
    #ifndef SYMBSIZE
      #define SYMBSIZE 10
    #endif
    typedef struct tabinfo
      {
        int  val;
        int  type;
        int  info;
      } tabdata;
    typedef struct tablemem
      {
        char    symbol[SYMBSIZE];
        tabdata symbdata;
      } tabletype;
    extern tabletype codetable[];  // supplied by test driver program
    extern int codetabsize;        // supplied by test driver program
    int storageincr(tablindx, operand)
    
    int tablindx;
    char operand[];
    Parameters:
    1. tablindx is the index in codetable of the storage directive
    2. operand is the operand 1 component
    Assumptions:
    The same assumptions are in effect as for opcodeincr (ie., (breakup and findlast have been run to produce the parameters needed). In addition, for storage directives, the type field in their tabinfo entries determines which directive is to be processed as follows:

     type directive
    5BYTE directive
    6WORD directive
    7RESB directive
    8RESW directive

    REMARK: operand is the operand 1 as determined by breakup.
    For the "BYTE" case with operand prefix X, the storage content of operand is a hex string, so the increment value is half of its length. In contrast, when the prefix is C, the storage content of operand is an ASCII string, so the increment value is just its length. It is an error in the X case for the length to be odd.

    Returned value:

    For "WORD", simply return the value 3.

    For "RESB" and "RESW", use the function sscanf to convert the value of operand to an integer. This is the value to return in the case of "RESB". Return 3 times this value in the case of "RESW". Since sscanf returns a number indicating how many arguments it successfully converted, if sscanf returns a value other than 1, an error in the numeric conversion is implied. Check for this and return -1 if it happens.

    The only storage directive which causes any problem at all is the storage directive "BYTE". In this case you need to scan operand counting the number of characters between the (single) quote marks. You can use the string function strtok first to get the text, using single quote as the only scanning delimiter; then use the string function strlen to find out how many characters are present. For the 'C' case, return the count. For the 'X' case return the count divided by 2 if the number of characters is even; otherwise return -1.
    File name:
    storageincr.c

    Procedure:

    • Design and construct a storageincr routine that conforms to the above specification. Note that the "nixbpe" values produced by breakup are not needed, since the codetable location of the opcode and the operand string produced by breakup provide the information needed to determine the increment amount.
    • Driver and makefile setup should have already have been taken care of in doing part A.
    • Devise a test plan for your subroutine that uses the driver to fully exercise your subroutine and covers all cases outlined above.

      When you are satisfied that you have an effective test plan, remove hlib.log and then run your tests. When finished, move hlib.log to a file named <student-id>-5.B.log for use in your Part B documentation in a manner analogous to that for Part A and for prior assignments.

      Examples:

      storageincr for WORD -123 should return 3
      storageincr for RESB 17 should return 17
      storageincr for BYTE X'ABC0' should return 2
      storageincr for BYTE X'ABC01' should return -1
      storageincr for BYTE C'A BIG FIVE' should return 10

Construct Word documentation as specified on the assignments page. Remember that your documentation file is to have 2 distinct parts, a write-up for Part A and a write-up for Part B, each with its own executive summary and set of appendices as noted above. Use the submit shell script from /usr/public/cop3601/cwinton to "shar" your

  • documentation (<student-id>-5.doc)
  • opcodeincr source code (opcodeincr.c)
  • storageincr source code (storageincr.c)
  • make file (<student-id>-5.makefile)
  • Part A log file (<student-id>-5.A.log)
  • Part B log file (<student-id>-5.B.log)
  • findlast source code (findlast.c)
  • breakup source code (breakup.c)
and "turnin" by noon on Friday, November 10 to cnw.3601.5. Late submissions can be submitted until the due date for the next assignment via submit to cnw.3601.5L (late points assessed as stipulated on the assignments page).