CS360 Midterm -- October 15, 2002. Answers.
Question 1: Answer
Straightforward assembler-crunching:
Procedure 1
a:
push #4
mov #5 -> %r0
st %r0 -> [fp]
ld [fp] -> %r0
add %r0, %g1 -> %r0
ret
Procedure 2
.globl tmp
s:
ld [fp+12] -> %r0
ld [r0] -> %r0
st %r0 -> tmp
ld [fp+16] -> %r0
ld [r0] -> %r0
ld [fp+12] -> %r1
st %r0 -> [r1]
ld tmp -> %r0
ld [fp+16] -> %r1
st %r0 -> [r1]
ret
Procedure 3
s:
ld [fp+12] -> %r0
mov #12 -> %r1
add %r0, %r1 -> %r0
ld [r0] -> %r0
ld [r0] -> %r0
ret
Procedure 4
This one is a little complex. It helps to start the arithmetic from the inside out:
- Multiply j by 3 and put the result in %r0
- Multiply k by 5 and put the result in %r1
- Add %r0 and %r1 and put them in %r0, so that 3*j+5*k is in %r0
- Multiply %r0 by 4 and add it to i, put the result in r0
- Dereference [r0] into %r0, so that i[3*j+5*k] is there.
- Subtract 3 from m and put the result in %r1
- Multiply %r1 by 4, and add it to %r0 -- now (i[3*j+5*k] + (m-3)) is in %r0.
- Dereference [r0] into %r0 and return.
s:
st %r2 -> [sp]--
ld [fp+16] -> %r0 / Step 1
mov #3 -> %r1
mul %r0, %r1 -> %r0
ld [fp+20] -> %r1 / Step 2
mov #5 -> %r2
mul %r1, %r2 -> %r1
add %r0, %r1 -> %r0 / Step 3
mov #4 -> %r1 / Step 4
mul %r0, %r1 -> %r0
ld [fp+12] -> %r1
add %r0, %r1 -> %r0
ld [r0] -> %r0 / Step 5
ld [fp+24] -> %r1 / Step 6
mov #3 -> %r2
sub %r1, %r2 -> %r1
mov #4 -> %r2 / Step 7
mul %r1, %r2 -> %r1
add %r0, %r1 -> %r0
ld [r0] -> %r0 / Step 8
ld ++[sp] -> %r2
ret
For further detail, the following files have main()s in them so that you can run
them under jassem. Each file has its main() in a comment:
Question 2: Answer
Again, a straightforward question -- read in files using readdir(),
and put them into a 2-level red-black tree, keyed on the mtime field
of the stat struct, then on file name. You have to strdup()
the file name.
main()
{
struct stat buf;
JRB t1, t2, tmp, tmp2;
struct dirent *de;
DIR *d;
d = opendir(".");
if (d == NULL) { perror("opendir ."); exit(1); }
t1 = make_jrb();
for (de = readdir(d); de != NULL; de = readdir(d)) {
if (de->d_name[0] != '.') {
if (stat(de->d_name, &buf) != 0) {
perror(de->d_name);
exit(1);
}
tmp = jrb_find_int(t1, buf.st_mtime);
if (tmp == NULL) {
tmp = jrb_insert_int(t1, buf.st_mtime, new_jval_v((void *) make_jrb()));
}
t2 = (JRB) tmp->val.v;
jrb_insert_str(t2, strdup(de->d_name), JNULL);
}
}
jrb_rtraverse(tmp, t1) {
t2 = (JRB) tmp->val.v;
jrb_traverse(tmp2, t2) {
printf("%s\n", tmp2->key.s);
}
}
}
It's also in exam-q2.c if you'd like to compile it
and run it.
Question 3: Answer
Part 1: The setuid bit is part of the protection bits of a file, stored
in its inode. When the setuid bit of an executable file is set, then
whenever a user executes the file, the resulting process assumes the
user id of the file's owner. Essentially, the user becomes the file's
owner while executing that file.
You set the setuid bit of file f with:
UNIX> chmod 04755 f
Part 2: You first write a program that prints out the first line
of the file in question. That file's name should be hard-coded into
the executable, and that should be an absolute pathname. Then you
set the setuid bit of the program using the chmod command
above. Finally, you set the permissions of the file to something
like 0600 or 0400. Now, when another user runs the program, he/she
will assume your identity, and will be able to read the first line
of the file.
This cannot be done without the setuid bit, because otherwise you would
have to set the permissions of the file to be world readable (0644 or
0444), giving users access to all lines of the file, and not
just the first line.
Question 4: Answer
In jtar we maintain a red-black tree of the inodes of the files
that we have stored in the jtar file. If we are to bundle
up two files that are hard links to each other, they will have the
same inodes. Thus, when we go to save the second file, we will see
its inode in the red-black tree, and simply store the fact that the
file has multiple links. When it is time to untar the file, we
can use the information stored in the jtar file to create
the first file, and then to create the appropriate links to it.
Question 5: Answer
Again, straightforward assembler crunching.
main:
push #8
st %g0 -> [fp]
mtop:
ld stdin -> %r0
st %r0 -> [sp]--
st %g1 -> [sp]--
mov #4 -> %r0
st %r0 -> [sp]--
mov #-4 -> %r0
add %r0, %fp -> %r0
st %r0 -> [sp]--
jsr fread
pop #16
cmp %r0, %g0
ble mbot
ld [fp] -> %r0
add %r0, %g0 -> %r0
st %r0 -> [fp]
b mtop
mbot:
ret
Question 6: Answer
In Procedure 1:
- The first two lines and the last line of the procedure are executed exactly once.
That's three instructions.
- The code from mtop to the ``ble mbot'' statement is executed
exactly x/4+1 times. This is 12 instructions.
- The code from the ``ld [fp] -> %r0''
statement and mbot is executed
exactly x/4 times. This is 4 instructions.
- Fread is executed x/4+1 times. As stated in the assumptions,
this call takes an average of 10 instructions, plus read() calls.
The first call to fread() has to call read(). Thereafter,
it is called every 4192/4 times that fread() is called.
This means: 10(x/4+1) instructions, and 1 + (x div 4192)
read() system calls.
So the final tally is:
0.1 (3 + 12(x/4 + 1) + 4(x/4) + 10(x/4+1)) + 200(1 + (x div 4192))
microseconds
= 202.5 + .65x + 200(x div 4192) microseconds
This is approximatly 202.5 + .6977x microseconds
Procedure 2 differs from Procedure 1 in two ways:
- The read() call takes only three arguments. Therefore there
are only 10 instructions between mtop and the ``ble mbot''
statement.
- Read() is called instead of fread(). Since it is called
x/4+1 times, it contrubutes 200(x/4+1) microseconds.
So the final tally is:
0.1 (3 + 10(x/4 + 1) + 4(x/4)) + 200(x/4+1)
microseconds
= 200.4 + 50.25x microseconds
That's quite a difference.
Extra Credit: Answer
In the late eighties, King Crimson founder and lead guitarist
Robert Fripp ran a series of acoustic guitar workshops, called
``guitar craft,'' in Charles Town, WV. A touring group, called the
``League of Crafty Guitarists,'' resulted, playing throbbing and
rather manic guitar music to small venues around the country.
After a few years, Fripp rejoined with Adrian Belew, Bill Bruford
and Tony Levin, plus a few others to form the 4th iteration of King
Crimson.