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 -0.25 point, and each unanswered question is worth zero point.
Make sure you write down you name on the upper right corner first, otherwise I cannot give points to anonymous students!
Notation: The name of a local variable assumes different
roles in different parts of this test. In pseudocode or C code,
the name of a local variable refers to the variable itself.
In assembly code, unless otherwise noted, the name of a local
variable is the displacement from ebp in number of bytes
to the local variable. The same applies to parameters.
Types: int16 is a 16-bit signed integer, int32 is
a 32-bit signed integer, char is an 8-bit character. We assume all
addresses and pointers are 32-bit.
Conventions: Return values are returned by registers. 16-bit and
8-bit values are returned by ax, 32-bit values are returned by
eax.
sub1: ___ movl %esp,%ebp addl $lastLocalVar,%esp ... movl %ebp,%esp popl %ebp ret
pushl %ebp
pushl %esp
popl %ebp
movl %ebp,%esp
subl $4,%esp
v1, v2 and
v3 as local variables, v1 is allocated space on the stack
last. From a different perspective, v1 has the lowest address
when compared to all other local variables. Which of the following
definitions is consistent with this convention? (v1_size is the
size of v1 in bytes, and etc.)
In addition, the label lastLocalVar should be defined to the
displacement from ebp to the local variable that has the lowest
address.
oldBP = 0 v1 = oldBP - v1_size v2 = oldBP - v2_size v3 = oldBP - v3_size lastLocalVar = v3
oldBP = 0 v1 = oldBP - v1_size v2 = v1 - v2_size v3 = v2 - v3_size lastLocalVar = v3
oldBP = 0 v3 = oldBP - v3_size v2 = oldBP - v2_size v1 = oldBP - v1_size lastLocalVar = v1
oldBP = 0 v3 = oldBP - v3_size v2 = v1 - v2_size v1 = v2 - v1_size lastLocalVar = v1
oldBP = 0 v3 = oldBP + v3_size v2 = v1 + v2_size v1 = v2 + v1_size lastLocalVar = v1
int32, and returns the sum in
eax. Its C prototype is as follows:
int32 add2(int32 x, int32 y);
It is implemented by the following assembly code. Note that the prologue and epilogue code are omitted but assumed done correctly, as are definitions of the displacements:
add2: # displacement definiteions # prologue pushl %eax movl x(%ebp),%eax addl y(%ebp),%eax popl %eax # epilogue ret
Is there a problem with this subroutine? If so, what is it?
ax should be used instead of eax.
eax should not be pushed and popped.
x(%ebp) should be just x, and similarly for
y(%ebp).
movl and addl instructions should be swapped.
sub2.
How should we clean up the stack? Assume the parameters are useless after
the called subroutine returns. Select one of the choices to substitute
___.
pushl $52 pushw myVar(%ebp) call sub2 ___
subl $52,%esp
subl $52,%ebp
addl $6,%esp
popl $52
popw myVar(%ebp)\end{verbatim}
\item \begin{verbatim}popw myVar(%ebp)
popl $52
int32 f1(int32 x); int32 f2(int32 x); int32 f3(int32 x);
Assuming that v1 is a local variable of the caller, how do we
implement the following code?
v1 = f1(f2(f3(1234)));
pushl $1234
call f3
call f2
call f1
# clean up parameter
movl %eax,v1(%ebp) \end{verbatim}
\item
\begin{verbatim}pushl $1234
call f1
call f2
call f3
# clean up parameter
movl %eax,v1(%ebp) \end{verbatim}
\item
\begin{verbatim}pushl $1234
call f1
# clean up parameter
pushl %eax
call f2
# clean up parameter
pushl %eax
call f3
# clean up parameter
movl %eax,v1(%ebp) \end{verbatim}
\item
\begin{verbatim}pushl $1234
call f3
popl %eax
pushl %eax
call f2
popl %eax
pushl %eax
call f1
popl %eax
movl %eax,v1(%ebp) \end{verbatim}
\item
\begin{verbatim}pushl $1234
call f3
movl %eax,(%esp)
call f2
movl %eax,(%esp)
call f1
# clean up parameter
movl %eax,v1(%ebp) \end{verbatim}
\end{enumerate}
\item
I need to preserve the value of \verb'ebx' and \verb'ecx'. However,
the subroutine \verb'sub3' can potentially overwrite these two registers.
How do I preserve these registers? Assume the original code to call
\verb'sub3' is as follows:
\begin{verbatim} pushl $123 # 2nd parameter
pushl $94 # 1st parameter
call sub3
# parameter clean up code
pushl $123 # 2nd parameter pushl $94 # 1st parameter pushl %ebx pushl %ecx call sub3 popl %ecx popl %ebx # parameter clean up code
pushl $123 # 2nd parameter pushl $94 # 1st parameter pushl %ebx pushl %ecx call sub3 popl %ebx popl %ecx # parameter clean up code
pushl %ebx
pushl %ecx
pushl $123 # 2nd parameter
pushl $94 # 1st parameter
call sub3
# parameter clean up code
popl %ecx
popl %ebx\end{verbatim}
\item
\begin{verbatim}
pushl %ebx
pushl %ecx
pushl $123 # 2nd parameter
pushl $94 # 1st parameter
call sub3
popl %ebx
popl %ecx
# parameter clean up code
ebx and ecx
by the same stack used for parameter passing.
void *f4(void);
This means it returns a pointer (address), and there is no parameter. The following is the implementation in assembly language:
f4:
popl %eax
jmp (%eax)\end{verbatim}
The following is how this subroutine is used, assume \verb'mystery' is
a local variable of the caller:
\begin{verbatim} call f4
movl %eax,mystery(%ebp)\end{verbatim}
Choose the correct explanation.
\begin{enumerate}
\item The subroutine crashes (segmentation fault) when it attempts to
execute the \verb'jmp' instruction.
\item The subroutine crashes (segmentation fault) when it attempts to
execute the \verb'popl' instruction.
\item The subroutine does not crash, but the stack is not balanced.
\item \verb'mystery' (as a variable) stores the address of the
\verb'movl' instruction in the caller's code.
\item \verb'mystery' (as a variable) stores some unspecifiable value.
\end{enumerate}
\item
In C notation, ``\verb'int32 *p;''' means \verb'p' is a pointer to a
32-bit integer. ``\verb'int32 i;''' means \verb'i' is an 32-bit integer.
``\verb'&i''' means the address of \verb'i'. How do we store the address
of \verb'i' in \verb'p'? In other words, how do we implement
``\verb'p = &i;'''? Assume \verb'p' and \verb'i' are either local
variables or parameters.
\begin{enumerate}
\item \label{qAddrAssignment:A1}
\begin{verbatim}
movl i(%ebp),%eax
movl %eax,p(%ebp)\end{verbatim}
\item
\begin{verbatim}
movl i,%eax
addl %ebp,%eax
movl %eax,p(%ebp)\end{verbatim}
\item \label{qAddrAssignment:A2}
\begin{verbatim}
movl i,%eax
addl %ebp,%eax
movl p,%ebx
addl %ebp,%ebx
movl %eax,%ebx\end{verbatim}
\item
\begin{verbatim}
movl i,%eax
addl %ebp,%eax
movl p,%ebx
addl %ebp,%ebx
movl %ebx,%eax\end{verbatim}
\item \ref{qAddrAssignment:A1} and \ref{qAddrAssignment:A2}
\end{enumerate}
\item
A subroutine call should use the following code:
\begin{verbatim} pushl $1234
pushl myVar(%ebp)
call sub5
# parameter clean up
However, the programmer makes a mistake, and it becomes the following:
pushw $1234 pushl myVar(%ebp) call sub5 # parameter clean up
Assuming that the subroutine does not attempt to change the parameters, what is the result of the erroneous code? Assume the ``parameter clean up code'' is correct with respect to the parameters actually passed.
sub5.
call
instruction.
sub5 may not perform its
calculations correctly.
sub6 expects no parameters. What happens when the
following code is used to call sub6?
pushl $1234 pushl myVar(%ebp) call sub6 # parameter clean up
sub5.
call
instruction.
sub6
may not be correct.