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:
  1. Multiply j by 3 and put the result in %r0
  2. Multiply k by 5 and put the result in %r1
  3. Add %r0 and %r1 and put them in %r0, so that 3*j+5*k is in %r0
  4. Multiply %r0 by 4 and add it to i, put the result in r0
  5. Dereference [r0] into %r0, so that i[3*j+5*k] is there.
  6. Subtract 3 from m and put the result in %r1
  7. Multiply %r1 by 4, and add it to %r0 -- now (i[3*j+5*k] + (m-3)) is in %r0.
  8. 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: 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:

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.