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!
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?
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
movl p,%eax movl $0,%eax
movl p+offset_X_j,%eax movl $0,%eax
movl p,%eax movl $0,offset_X_j(%eax)
movl $0,offset_X_j(p)
movl $0,offset_X_j+p
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;
movl $23,a+offset_X_j[3]
movl $23,a+3*sizeof_X+offset_X_j
movl $3*sizeof_X,%eax movl $23,offset_X_j(%eax)
movl a,%eax movl $23,3*sizeof_X+offset_X_j(%eax)
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;
movl $12,x
movl $12,x+offset_X_j
movl $12,x+offset_X_j(%ebp)
movl $x,%eax movl $12,offset_X_j(%eax)
movl x,%eax addl %ebp,%eax movl $12,offset_X_j(%eax)
.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?
pushl x
pushl $x
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:
pushl $x+sizeof_X
pushl x+sizeof_X
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?
addl sizeof_X,ptr
addl $sizeof_X,ptr
addl $sizeof_X,ptr(%ebp)
movl ptr(%ebp),%eax addl $sizeof_X,(%eax)
ptr is pointing
an object on the stack or not.
oldEbp = 0 localArray = oldEbp - (10 * 4) sub1: pushl %ebp movl %esp,%ebp addl $localArray,%esp ...
Which C expression will corrupt the return address?
localArray[0] = 0;
localArray[10] = 0;
localArray[11] = 0;
localArray has nothing to do with
the stack.
localArray has an address higher
than that of the return address of sub1.
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
int is a 32-bit integer.
void f(int x, int *y)
{
int i;
int j;
// statements
}
y points to.
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);
movl someVar,%eax
movl $someVar,%ebx movl (%ebx),%eax
movl $someVar,%ebx
movl someVar(%ebx),%eax
movl $someVar,(%eax)
movl $someVar,(%ebx) movl (%ebx),%eax
O flag and Z be set (don't worry about the other flags)?
cmpl %eax,%ebx
%eax = 0x80000000 and %ebx = 0x80000000
%eax = 0x80000000 and %ebx = 0x7fffffff
%eax = 0x7fffffff and %ebx = 0x80000000
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?
jb L1
jz L1
jg L1
jz L0 jnc L1 L0:
jnc L1 jnz L1
struct X *p1 is a parameter
struct X *p2 is a parameter
int num is an auto local variable
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;
movl p2+offset_X_j(%ebp),%eax addl num(%ebp),%eax movl %eax,p1+offset_X_i
movl p2+offset_X_j(%ebp),p1+offset_X_i(%ebp) addl num(%ebp),p1+offset_X_i(%ebp)
movl p2(%ebp),%eax movl offset_X_j(%eax),%ebx addl num(%ebp),%ebx movl p1(%ebp),%eax movl %ebx,offset_X_i(%eax)
movl p2+offset_X_j,%eax addl num(%ebp),%eax movl %eax,p1+offset_X_i
S flag is set after the following instruction,
what do we know about the registers?
cmpl %eax,%ebx
%eax is (unsigned) greater than %ebx
%eax is (signed) greater then %ebx
%ebx is (unsigned) greater than %eax
%ebx is (signed) greater then %eax
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.
pushl %eax call bart popl %eax cmpl %eax,%eax jnz yikes addl $4,%esp
pushl %eax call bart cmpl %eax,%eax jnz yikes addl $4,%esp
pushl %eax call bart cmpl %eax,(%esp) jnz yikes addl $4,%esp
pushl %eax call bart cmpl %eax,4(%esp) jnz yikes addl $4,%esp
movl $1,%eax
movl %eax,(%ebx)
movl 1(%ebx),%eax
movl 1,(%eax)
movl 1,%eax
ja
jb
jz
jo
%eax? The answer has to work for all possible
initial values of %eax.
addl %eax,%eax
%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
ja instruction, which other replacement
instruction can be used in all cases for the following situation?
cmpl $0,%eax ja L0
jb
jnb
jg
jnz
ja.
cmpl %ebx,%eax
%eax is less than %ebx unsigned
%ebx is less than %eax signed
%eax is not less than %ebx unsigned
%ebx is no less than %eax signed
%eax is less than %ebx signed
call sub1
ret
movl $0,0
popl %eax
addl $4,%esp