Practice Final

Prof. Tak Auyeung

Instructions: You may bring any material that is handwritten or printed prior to the examination to help you. You can also bring a calculator if you think it may help you. However, you can only use the calculator for numerical computations only.

You, as an individual, are expected to do your own work. This means you cannot seek, receive or otherwise acquire any assistance except clarifications from the professor during an examination. Any communication involving the contents of the subject matter or the examination is considered cheating. Do not initiate or accept such communication, or the result of your examination is automatically voided.

Each correct answer is worth one point, each wrong answer is worth zero point, and each unanswered question is also worth zero point. This means you should guess and leave no question unanswered.

Make sure you write down you name on the upper right corner first, otherwise I cannot give points to anonymous students!

  1. The following is the C code representation of a record (structure):

    struct X
    {
      int i;
      int j;
    };
    

    Assume that an int is a 32-bit integer. How many bytes should be allocated for a variable of this type?

    1. 32
    2. 4
    3. 8
    4. 2
    5. 64
  2. Refer to question 1, we add a global variable definition as follows:

    struct X *p;
    

    In a program, we need to perform the following:

    p->j = 0;
    

    How do we implement this in assembly? Assume offset_X_field is the offset in number of bytes from the base of a struct X object.

    Also, assume that p is declared as follows:

    .data
    p: .fill 1,4,0
    

    1. movl p,%eax
      movl $0,%eax
      
    2. movl p+offset_X_j,%eax
      movl $0,%eax
      
    3. movl p,%eax
      movl $0,offset_X_j(%eax)
      
    4. movl $0,offset_X_j(p)
      
    5. movl $0,offset_X_j+p
      
  3. Refer to question 1. Now we add an array definition in C:

    struct X a[10];
    

    Assume that sizeof_X is a symbol defined to the number of bytes of a struct X object.

    How do we implement the following statement in assembly:

    a[3].j = 23;
    

    1. movl $23,a+offset_X_j[3]
      
    2. movl $23,a+3*sizeof_X+offset_X_j
      
    3. movl $3*sizeof_X,%eax
      movl $23,offset_X_j(%eax)
      
    4. movl a,%eax
      movl $23,3*sizeof_X+offset_X_j(%eax)
      
    5. All of the above implement the C statement
  4. Refer to question 1. Assume we allocate a local variable from the stack. Symbols are defined as follows:

      oldEbp = 0
      x = oldEbp - sizeof_X
    

    The matching code to perform the allocation at run time is as follows:

    pushl  %ebp
    movl  %esp,%ebp
    addl  $x,%esp
    

    Given these assumptions, how do we perform the following statement in assembly?

    x.j = 12;
    

    1. movl $12,x
      
    2. movl $12,x+offset_X_j
      
    3. movl $12,x+offset_X_j(%ebp)
      
    4. movl $x,%eax
      movl $12,offset_X_j(%eax)
      
    5. movl x,%eax
      addl %ebp,%eax
      movl $12,offset_X_j(%eax)
      
  5. Refer to questio 1. Assume we allocate a global (static) variable. Symbols are defined as follows:

    .data
    x: .fill 1, sizeof_X, 0
    

    Now, we need to call a subroutine expecting a single parameter that is of struct X type. How do we pass x as a parameter?

    1. pushl x
      
    2. pushl $x
      
    3.   subl $sizeof_X,%esp
        movl %esp,%ebx
        movl $x,%eax
      L0:
        cmpl $x+sizeof_X, %eax
        jnb  L1
        movl (%eax),%ecx
        movl %ecx,(%ebx)
        addl $4,%eax
        addl $4,%ebx
        jmp  L0
      L1:
      
    4. pushl $x+sizeof_X
      
    5. pushl x+sizeof_X
      
  6. Refer to 1. ptr is a local variable pointer to a struct X. How do we implement the C code ++ptr so that ptr points to the next struct X object?
    1. addl sizeof_X,ptr
      
    2. addl $sizeof_X,ptr
      
    3. addl $sizeof_X,ptr(%ebp)
      
    4. movl ptr(%ebp),%eax
      addl $sizeof_X,(%eax)
      
    5. Cannot be determined because we don't know if ptr is pointing an object on the stack or not.
  7. In a subroutine, we need to allocate an array of 10 32-bit integers as the only (auto) local variable. This is done by the following code:

      oldEbp = 0
      localArray = oldEbp - (10 * 4)
    sub1:
    pushl  %ebp
    movl   %esp,%ebp
    addl   $localArray,%esp
    ...
    

    Which C expression will corrupt the return address?

    1. localArray[0] = 0;
    2. localArray[10] = 0;
    3. localArray[11] = 0;
    4. None of the above because localArray has nothing to do with the stack.
    5. None of the above because localArray has an address higher than that of the return address of sub1.
  8. Describe the result of executing the following code.

    pushl %eax
    pushl %ebx
    pushl %ecx
    pushl %edx
    movl  $4,%eax
    movl  $1,%ebx
    pushl $'\n'
    movl  %esp,%ecx
    movl  $1,%edx
    int   $0x80
    addl  $4,%esp
    popl  %edx
    popl  %ecx
    popl  %ebx
    popl  %eax
    
    1. Nothing
    2. It writes a newline character to the standard output file. There is no problem.
    3. It reads a character from the standard input file. There is no problem.
    4. It crashes.
    5. It does something useful, and it does not crash immediately. But, the stack is left unbalanced.
  9. Using our standard method to allocate parameters and local variables from the stack, how many bytes are required every time we call the following subroutine? Assume each int is a 32-bit integer.

    void f(int x, int *y)
    {
      int i;
      int j;
    
      // statements
    }
    
    1. 4
    2. 8
    3. 16
    4. 24
    5. Cannot be determined because we don't know the size of the array that y points to.
  10. j and k are both local variables of int type. What assembly code passes j+k as a parameter to subroutine s1? In other words, how do we implement the following C code?

    s1(j+k);
    

    1. pushl  j+k
      
    2. pushl  j+k(%ebp)
      
    3. pushl  j(%ebp)
      movl   k(%ebp),%eax
      addl   %eax,(%esp)
      
    4. movl   j(%ebp),%eax
      addl   k(%ebp),%eax
      pushl  %eax
      
    5. 10c and 10d
  11. Some architectures do not have the direct addressing mode. How else can we implement the following instruction?

    movl someVar,%eax
    
    1. movl $someVar,%ebx
      movl (%ebx),%eax
      
    2. movl $someVar,%ebx
      
    3. movl someVar(%ebx),%eax
      
    4. movl $someVar,(%eax)
      
    5. movl $someVar,(%ebx)
      movl (%ebx),%eax
      
  12. Consider the following instruction. In which case will both the O flag and Z be set (don't worry about the other flags)?

    cmpl %eax,%ebx
    
    1. %eax = 0x80000000 and %ebx = 0x80000000
    2. %eax = 0x80000000 and %ebx = 0x7fffffff
    3. %eax = 0x7fffffff and %ebx = 0x80000000
    4. None of the above, but there is such a case
    5. None of the above, but such a case does not exist
  13. The instruction ja often does not exist on most other architectures. How can we implement it using other instructions? For example, how do we implement ja L1 for all cases?
    1. jb L1
      
    2. jz L1
      
    3. jg L1
      
    4. jz  L0
      jnc L1
      L0:
      
    5. jnc L1
      jnz L1
      
  14. Refer to question 1. Assume the following:

    Assuming that in assembly, the name of each parameter or variable is the displacement from %ebp, how do we implement the following statement?

    p1->i = p2->j + num;
    

    1. movl  p2+offset_X_j(%ebp),%eax
      addl  num(%ebp),%eax
      movl  %eax,p1+offset_X_i
      
    2. movl  p2+offset_X_j(%ebp),p1+offset_X_i(%ebp)
      addl  num(%ebp),p1+offset_X_i(%ebp)
      
    3. movl  p2(%ebp),%eax
      movl  offset_X_j(%eax),%ebx
      addl  num(%ebp),%ebx
      movl  p1(%ebp),%eax
      movl  %ebx,offset_X_i(%eax)
      
    4. movl p2+offset_X_j,%eax
      addl num(%ebp),%eax
      movl %eax,p1+offset_X_i
      
    5. 14a and 14b
  15. If the S flag is set after the following instruction, what do we know about the registers?

    cmpl  %eax,%ebx
    
    1. %eax is (unsigned) greater than %ebx
    2. %eax is (signed) greater then %ebx
    3. %ebx is (unsigned) greater than %eax
    4. %ebx is (signed) greater then %eax
    5. not one of the above can be confirmed
  16. We suspect that a subroutine bart modifies register eax. In order to confirm this, we try to write some code so that we jump to label yikes if and only if register eax is modified by subroutine bart. Which of the following invocation code does this?

    We assume subroutine bart does not have any parameters, and it does not return any value. Also, the stack needs not be balanced when we get to yikes.

    1. pushl %eax
      call  bart
      popl  %eax
      cmpl  %eax,%eax
      jnz   yikes
      addl  $4,%esp
      
    2. pushl %eax
      call  bart
      cmpl  %eax,%eax
      jnz   yikes
      addl  $4,%esp
      
    3. pushl %eax
      call  bart
      cmpl  %eax,(%esp)
      jnz   yikes
      addl  $4,%esp
      
    4. pushl %eax
      call  bart
      cmpl  %eax,4(%esp)
      jnz   yikes
      addl  $4,%esp
      
    5. all of the above code will do it
  17. An operand of which of the following addressing modes always provides the same value?
    1. immediate
    2. register
    3. direct
    4. indirect
    5. indexed
  18. Which of the following is not a valid instruction?

    1. movl $1,%eax
      
    2. movl %eax,(%ebx)
      
    3. movl 1(%ebx),%eax
      
    4. movl 1,(%eax)
      
    5. movl 1,%eax
      
  19. Which conditional jump is not supported by the 386 architecture?
    1. ja
    2. jb
    3. jz
    4. jo
    5. all of the above are supported
  20. If the following instruction is repeated 33 times, what will be the value of register %eax? The answer has to work for all possible initial values of %eax.

    addl  %eax,%eax
    
    1. 0
    2. the most positive value of a 32-bit signed number
    3. the most positive value of a 32-bit unsigned number
    4. the most negative value of a 32-bit signed number
    5. 32
  21. Assume that %eax has a value of 23 (in decimal) initially. What is the value of %eax after the following instructions?

    pushl  %eax
    addl   %eax,(%esp)
    addl   %eax,%eax
    addl   %eax,%eax
    addl   %eax,%eax
    addl   %eax,(%esp)
    popl   %eax
    
    1. 23
    2. 230
    3. 46
    4. 184
    5. 0
  22. Instead of using the ja instruction, which other replacement instruction can be used in all cases for the following situation?

      cmpl  $0,%eax
      ja    L0
    
    1. jb
    2. jnb
    3. jg
    4. jnz
    5. None of the above can replace ja.
  23. After the following instruction, the carry flag is set. What can we know for sure?

    cmpl %ebx,%eax
    
    1. %eax is less than %ebx unsigned
    2. %ebx is less than %eax signed
    3. %eax is not less than %ebx unsigned
    4. %ebx is no less than %eax signed
    5. %eax is less than %ebx signed
  24. Which of the following instructions does not access (read or write) memory (other than the instructions)?
    1. call sub1
    2. ret
    3. movl $0,0
    4. popl %eax
    5. addl $4,%esp


Copyright © 2004-12-12 by Tak Auyeung