CMPE 401 - Computer Interfacing

Assignment #1 Solutions

Due: In the CMPE 401 assignment box at 15:45 on Friday, Sept. 19, 2003


  1. List ten of the most likely places that you would find a microprocessor or microcontroller in a typical furnished home?

    Here is a list of seventeen likely places:
    1. Personal computer
    2. Router and/or hub
    3. Stereo system (receiver, tape deck, CD player, DVD player, etc.)
    4. Cell phone
    5. Game computer
    6. Microwave oven
    7. Security system
    8. MP3 player
    9. Car (dashboard, entertainment system, ignition system, anti-lock
       brakes, navigation system, etc.)
    10. Calculator
    11. Electronic thermostat
    12. Digital camera
    13. Clock radio
    14. Personal data assistant
    15. Laser printer
    16. Modem
    17. Hearing aid
    

  2. The CPU32 microprocessor inside the MC68332 microcontroller requires 2 clock cycles to excute the NOP instruction. Assume that, as with the lab microcomputer, the CPU clock frequency is 16.78 Mhz. Now consider a CPU32 that begins executing a very long program that contains only NOP instructions. This program could be printed out on sheets of paper, with 13 lines every 5 cm, and hence 66 lines per page. Assume that a stack of 500 pages is about 5 cm thick. What would be the thickness of the portion of the program listing corresponding to the instructions that could be executed by the CPU32 in one second?

    Number of instructions in one sec = 8390000
    Number of pages in listing = 8390000 / 66 = 127121
    Thickness of program listing = 127121 * (5 cm / 500) = 12.71 m
    

  3. Briefly explain how the data and instruction cache memories inside a modern microprocessor speed up the execution of typical programs.

    In most programs there is "locality of reference", which means that
    once a data item or an instruction has been used once in a program,
    there is a fairly high probability that it will be used again very
    soon in the same program.  Because accessing data and instructions
    from off of the CPU chip is relatively slow, it makes sense to store
    local copies on the CPU chip of the most recently used data items 
    and instructions.  A cache memory is a fast on-chip memory that is
    used to store such local copies of data items.  For most of the time,
    the CPU will be able to retrieve data items and instructions from
    the faster cache memory instead of going off-chip to slower memory.
    In this way, the instruction execution rate of programs can be 
    significantly increased.
    

  4. Design a CPU32 assembly language program that retrieves data items that are stored in a packed array containing NUM_RECORDS records. Each record contains the following fields: (1) two 8-bit unsigned integers, (2) one 16-bit integer, (3) two BCD digits, and (4) three ASCII codes. Your program is to receive the following input parameters: (1) a pointer in A0.L to the first byte in the first record; (2) the position in A1.W of the desired record, from 0 up to NUM_RECORDS-1; (3) the identity in D0.B of the requested field, from 0 to 7. The requested information is to be returned in D7.L, right-justified in a field of zeros.

    /*  Subroutine: RETRIEVE
        Purpose:  Retrieves the contents of one of eight fields in
                  one record from an array of records.
        Inputs: A0.L  Base address of the array of records
                A1.W  (0...NUM_RECORDS-1) Index of the desired record
                D0.B  (0...7) Index of the desired field in the record
        Output: D7.L  The retrieved field contents, right justified
    */
    RETRIEVE:
    	MOVEM.L A0-A6/D0-D6,-(SP)   /* save regs */
            CLR.L   D7                  /* default return value */
            CMPI.W  #NUM_RECORDS,A1     /* range check on record index */
            BHS     EXIT_RETRIEVE
    
            LEA.L   (0,A0,A1.W*8),A0    /* point to start of record */
    
    F0:     TST.B   D0                  /* check field index against 0 */
            BHI     F1
            MOVE.L  (A0),D7
            ANDI.L  #0xFF000000,D7      /* mask away all but 1st 8-bit int */
            ROL.L   #8,D7               /* rotate int into position */
            BRA     EXIT_RETRIEVE
    
    F1:     CMPI.B  #1,D0               /* check field index against 1 */
    	BHI     F2
            MOVE.L  (A0),D7
            ANDI.L  #0x00FF0000,D7      /* mask away all but 2nd 8-bit int */
            LSR.L   #8,D7               /* shift int into position */
            LSR.L   #8,D7
            BRA     EXIT_RETRIEVE
    
    F2:     CMPI.B  #2,D0               /* check field index against 2 */
    	BHI     F3
            MOVE.L  (A0),D7
            ANDI.L  #0x0000FFFF,D7      /* mask away all but 16-bit int*/
            BRA     EXIT_RETRIEVE
    
    F3:     CMPI.B  #3,D0               /* check field index against 3 */
    	BHI     F4
            MOVE.L  4(A0),D7
            ANDI.L  #0xF0000000,D7      /* mask away all but first BCD */
            ROL.L   #4,D7               /* rotate BCD into position */
            BRA     EXIT_RETRIEVE
    
    F4:     CMPI.B  #4,D0               /* check field index against 4 */
    	BHI     F5
            MOVE.L  4(A0),D7
            ANDI.L  #0x0F000000,D7      /* mask away all but second BCD */
            ROL.L   #8,D7               /* rotate BCD into position */
            BRA     EXIT_RETRIEVE
    
    F5:     CMPI.B  #5,D0               /* check field index against 5 */
    	BHI     F6
            MOVE.L  4(A0),D7
            ANDI.L  #0x00FF0000,D7      /* mask away all but 1st ASCII */
            LSR.L   #8,D7               /* shift ASCII into position */
            LSR.L   #8,D7
            BRA     EXIT_RETRIEVE
    
    F6:     CMPI.B  #6,D0               /* check field index against 6 */
    	BHI     F7
            MOVE.L  4(A0),D7
            ANDI.L  #0x0000FF00,D7      /* mask away all but 2nd ASCII */
            LSR.L   #8,D7               /* shift ASCII into position */
            BRA     EXIT_RETRIEVE
    
    F7:     CMPI.B  #7,D0               /* check field index against 7 */
    	BHI     EXIT_RETRIEVE
            MOVE.L  4(A0),D7
            ANDI.L  #0x000000FF,D7      /* mask away all but 3rd ASCII */
    
    EXIT_RETRIEVE:
    	MOVEM.L (SP)+,A0-A6/D0-D6   /* restore regs */
            RTS
    

  5. Design a subroutine, called TRANSPOSE, that creates a copy of a given two-dimensional source array of bytes in which the storage order has been changed from column major order to row major order, and the bytes have been sign-extended into words. Recall that in column major order, the elements of the first column are stored first (while incrementing the row position), then the elements of the second column, and so on until the last elements in the last column are stored. In row major order, the elements of the first row are stored first (while increasing the column position), then the elements of the second row, and so on until the last elements of the last row are stored. The base addresses of the source and destination arrays are to be passed as parameters in registers A0.L and A1.L, respectively. The number of rows and columns in the source array are given in registers D5.W and D6.W, respectively. The contents of all CPU registers are to be restored to their original values by the end of the subroutine. Use the LEA instruction to perform any pointer operations.

    /*  Subroutine: TRANSPOSE
        Inputs:  A0.L  Base address of input byte array (column major order)
                 A1.L  Base address of output word array (row major order)
                 D5.W  Number of rows in the input array
                 D6.W  Number of columns in the input array
        Outputs: Output array has word-sized elements (sign extended from
                 bytes in input array), and the storage order is row major.
        Variables: A2.L  Pointer into input array
                   A3.L  Pointer into output array
                   D0.W  Current row in input array
                   D1.W  Current column in input array
                   D7.W  Data element
    */
    TRANSPOSE:
          MOVEM.L A0-A6/D0-D7,-(SP)    /* Save regs */
    
          CLR.W   D0                   /* Clear input row index */
          CLR.W   D1                   /* Clear input col index */
          MOVEA.L A0,A2                /* Init input array element pointer */
          MOVEA.L A1,A3                /* Init output array element pointer */
    
    LOOP: MOVE.B  (A2)+,D7             /* Read next byte from input array */
          EXT.W   D7                   /* Sign extend */
          MOVE.W  D7,(A3)              /* Write word to output array */
          LEA.L   (0,A3,D6.W*2),A3     /* Advance output array pointer */
          ADDQ.W  #1,D0                /* Increment row index */
          CMP.W   D0,D5                /* End of input column? */
          BHI     LOOP                 /* No, go get next element in same col */
                                       /* Yes, go to top of next input col */
          CLR.W   D0                   /* Clear row index */
          ADDQ.W  #1,D1                /* Increment column index */
          LEA.L   (0,A1,D1.W*2),A3     /* Reform output array pointer */
          CMP.W   D1,D6                /* Past last input column? */
          BHI     LOOP                 /* No, start working on input column */
                                       /* Yes, exit routine */
          MOVEM.L (SP)+,A0-A6/D0-D7    /* Restore regs */
          RTS