Assignment #5: Intel x86 Assembly, Procedures, and the Stack Frame

Assigned: Monday, Mar. 30
Due: Wednesday, Apr. 8 by midnight

Contents:


Overview

Topic: The Intel x86 ISA, x86 Assembly Programming, Procedure Calls, and the Stack Frame
Related Reading: class notes and Chapter 3 (esp. sections 3.7 and 3.8)


Practice Problems

Practice problems from the textbook (answers are at the end of the chapter):


Problems to be Submitted (25 points)

When you turn in your assignment, you must include a signed cover sheet (PDF version) with your assignment (you're assignment will not be graded without a completed cover sheet).

You are allowed to submit your assignment via email, but if you choose to do so, you must bring a hardcopy of your assignment along with a completed cover sheet to the instructor at the next class. (Note: Do not email the instructor any .zip file attachments, as SLU's email may not accept these emails; i.e. the instructor may not receive your email.)

  1. (2 points)

    What operation is performed by the following sequence of instructions?

          pushw  %ax 
          pushw  %dx 
          popw   %ax 
          popw   %dx 
    

  2. (5 points)

    Create an assembly program that computes the volume of a trapezoidal prism, given the integer sizes for A, B, H, and L.

    Use a procedure to compute the volume, and have that procedure take four input arguments: length of the prism (L), the height of the trapezoidal cross-section (H), the base width of the trapezoid (B), and the top width of the trapezoid (A). The corresponding procedure declaration in C would look lie:

        int tpVol = volTrapPrism (int L, int H, int A, int B);

    Assume: For this problem, use a variable size of 4 bytes (32 bits) for all variables.

    Note: Be sure to use the C/C++ calling protocol for passing arguments and managing the stack frame.

    You're welcome to use a similar program, like abs_asm.s, as a starting point for your answer. Remember, the commands to build an assembly file like abs_asm.s are:

          as --32 abs_asm.s -o abs_asm.o
          gcc -m2 abs_asm.o -o abs_asm
    

  3. (2 points)

    Given the four major sections of a process' memory organization (Text, Data, Heap, and Stack), indicate which area each of the following are stored in:

    1. local variables
    2. program code
    3. dynamically-allocated variables, instantiated via new or malloc()
    4. global variables

  4. (8 points)

    For this problem you are given the assembly code: hw5_code.s. This code contains a procedure, some_procedure(), which performs some computation over the elements in an array.

    Given this code, answer the questions below:

    1. In the procedure, which register holds the loop counter? How many iterations does the loop execute (i.e. how many times is the loop body executed) ?

    2. Where is the array stored (in which area of memory, relative to the virtual memory organization for the process)? Within the procedure, which register holds the address of the array? Which register holds the value of an individual array element?

    3. Why are there two imul instructions in the procedure?

    4. What is the purpose of the  sarl $2, %eax  instruction?   Hint: There is some correlation with both the answer from part a), and the number of elements in the array...

    5. What mathematical formula does this procedure compute?

    6. What is the purpose of the  pushl %esi  and  pushl %ebx  instructions, and the  popl %ebx  and  popl %esi  instructions, at the top and bottom of some_procedure(), respectively?

    7. (2 points)

      Assuming the processor is currently executing the loop in some_procedure(), give a diagram showing the organization of the stack, including the stack frames for both main() and some_procedure(). As done in class, identify (via value or description) the contents of each element on the stack.

    Hint: This code is relatively similar to an example covered in class.

  5. (8 points)

    Given the following code:

          SomeProcedure:
                cmpl  %ebx, %eax
                jle   L1
                subl  %ebx, %eax
                jmp   L2
    
             L1:
                subl  %eax, %ebx
                movl  %ebx, %eax
    
             L2:
                movl  $0, %ecx
                addl  %eax, %ecx
                addl  %ecx, %edx
                ret
    
    1. (2 points)

      What is the calling protocol for the procedure?   In other words...

      • With repect to input argument(s):   How many input args are there?   How are they passed in?
      • With repect to return argument(s):   How many are there?   How are they passed out?

          Hint: You might want to double-check your count on the number of input args...

    2. (1 point)

      What does this procedure do?   If possible, give an equation in terms of the inputs...

    3. (5 points)

      This implementation is fairly inefficient, and doesn't follow the C/C++ calling protocol. Modify the original version of SomeProcedure() to correct this, including:

      1. Assume you have an abs() procedure in your libraries (such as the one in abs_asm.s). Use the abs() procedure to simplify SomeProcedure().
      2. Modify SomeProcedure() to use the C/C++ calling protocol -- i.e. to use a stack frame and pass arguments as appropriate through either the stack or register(s).

      In addition to the modified version of SomeProcedure(), give a snippet of code from a sample parent procedure that demonstrates a call to SomeProcedure(), with appropriate inputs.