CS360 Midterm Exam #1. March 1, 2018. James S. Plank
Answers and Grading
You can compile and run the programs yourself (you'll have to
compile last two with -m32).
Question 1: 27 points
- 0: Left shifting by 16 is the same as left-shifting by four hex digits. The leftmost
four digits will be shifted "off" the word. Zeroes will shift into the rightmost four
digits. So the answer is 0x992b0000.
- 1: Right shifting by 12 is the same as right-shifting by three hex digits.
So the answer is 0x00014a7d.
- 2: This turns the digits that correspond to zeros in m to zeros in z.
The answer is 0x9108e0c9.
- 3: This turns the digits that correspond to f's in m to zeros in x.
The answer is 0x00a00900.
- 4: This turns the digits that correspond to f's in m to f's in y.
The answer is 0xffaffeff.
- 5: (x^x) equals zero and XOR is associative. This is simply y
The answer is 0x14a7de7e.
- 6: The AND turns y into 0x00a7de00. The left-shift shifts it by two hex digits.
The answer is 0xa7de0000.
- 7: This is equivalent to NOT -- 0's go to 1's and 1's go to 0's. So, (0101 1011)
becomes (1010 0100). The answer is 0xa4.
- 8: c left-shifted by 4 bits is 0x5b0. Since d is a char, you only retain
the right two digits: 0xb0.
- 9: c left-shifted by one bit is (0101 1011 0) = (0 1011 0110). You lose the left
most bit, so the answer is 0xb6.
0: 0x992b0000
1: 0x00014a7d
2: 0x9108e0c9
3: 0x00a00900
4: 0xffaffeff
5: 0x14a7de7e
6: 0xa7de0000
7: 0xa4
8: 0xb0
9: 0xb6
Grading
Three points for each of lines 0 through 6. Two points for the others.
Question 2: 20 points
- Here's ASCII art of buf and x after the strcpy():
012345678
^ ^
| |
buf x
The strcat() statement finds the end of s, and puts "Fred"
there, so now the bytes become:
012345678Fred
^ ^
| |
buf x
So the first tw lines are:
0: '012345678Fred'
1: '5678Fred'
- 2: This is integer arithmetic on characters. The odd characters
in buf don't change. The even characters change as follows:
- buf[0] is 'A' + 0 = 'A'.
- buf[2] is 'B' + 1 = 'C'.
- buf[4] is 'C' + 2 = 'E'.
- buf[6] is 'D' + 3 = 'G'.
- buf[7] is 'E' + 4 = 'I'.
So the answer is: 'AACBECGDIE'
- After the first strcpy(), we have the following.
I'll use asterisks for null characters:
JJKKLLMMNNOOPPQQRRSS*
^ ^ ^
| | |
buf x y
After the second strcpy(), we have:
JJKKLLMMNNAABB*QRRSS*
^ ^ ^
| | |
buf x y
And after the last strcpy(), we have:
JJKKLUVWXYZ*BB*QRRSS*
^ ^ ^
| | |
buf x y
So, the output statements are:
3: 'JJKKLUVWXYZ'
4: 'LUVWXYZ'
5: 'XYZ'
6: 'BB'
7: 'RRSS'
- 8: (y-x) is five, so this prints buf[5], which is '5'.
- 9: This increments y by ('4'-'0'), which is 4. So
this prints buf[10+4+3]: 'H'
0: '012345678Fred'
1: '5678Fred'
2: 'AACBECGDIE'
3: 'JJKKLUVWXYZ'
4: 'LUVWXYZ'
5: 'XYZ'
6: 'BB'
7: 'RRSS'
8: 5
9: H
Grading
- Two points for each line.
- If line 1 was the same as line 0, but with the first 5 characters gone, you received
full credit.
- For each of lines 4 through 7, if they were the same as their previous lines, but
with the first four characters gone, you received full credit.
Question 3: 12 points
- Both c and ip point to the same bytes.
When you access c, you get the bytes in the order in which
they appear in memory. When you access ip, you get sets of
four bytes interpreted as integers in little endian format. So,
when you print ip[0], you get the bytes (0x21, 0x91, 0x86
and 0x99) printed as an integer in little endian: 0x99869221.
- ip[1] gets you the next four bytes in little endian:
0x74795106.
- We first copy the first two bytes of ip[0],
which are 0x21 and 0x91, to vp. Next, we copy the
first two bytes of ip[1], which are 0x06 and 0x51,
to the third and fourth bytes of vp. When we print v
as an integer, it prints the bytes in little endian: 0x51069121.
- When we print the bytes as chars, they come out in the order
in which they appear in memory: 0x21, 0x91, 0x06, 0x51.
The last memcpy copies the bytes 0x86, 0x99, 0x06 and 0x51, to
v. When I add 0x01100220, that is done in little endian, so
it adds 0x01 to 0x51, 0x10 to 0x06, 0x02 to 0x99 and 0x20 to 0x86.
Therefore, the answer is: 0xa6, 0x9b, 0x16, 0x52
0: 0x99869121
1: 0x74795106
2: 0x51069121
3: 0x21 0x91 0x06 0x51
4: 0xa6 0x9b 0x16 0x52
Grading
- Three points for each of lines 0 and 1.
- Two points for the others.
- You got full credit for line 3 if it matched line 2 (printing the bytes in reverse order).
- You got 1 point for "0x52 0x16 0x9b 0xa6" in line 4.
Question 4: 21 points
- 0: The array x is simply the
numbers in order as printed in the third column.
So *x is 1749172220
- 1: And x[5] is the 6th integer in
the third column: 1749172192
- 2: e is 0x68423fe0. That means that *e the value at
that address: 0x68423ffc. That means that **e is
the value at address 0x68423ffc: 1749172232.
- 3: e is 0x68423fe0. That means that e+2
is 0x68423fe8. So e[2] is 0x68423ffc. That means
that e[2]+1 is 0x68424000.
And e[2][1] is the value at 0x68424000: 1749172200.
- 4: f is 0x68423fe0. That means that *f
is the same as *x: 1749172220.
- 5: f is 0x68423fe0.
That means that *f is 0x68423ffc.
Which means that **f is 0x68424008.
Which means that ***f is 1749172244.
- 6: e is 0x68423fe0. Adding 8 to it is pointer
arithmetic, which really adds 32, or 0x20 to it. So the answer is
0x6842400.
- 7: f is 0x68423fe0.
That means that f+3 is 0x68423fec.
Which means that f[3] is 0x68423ff4.
Which means that f[3][0] is 0x68423fe0.
Which means that f[3][0]+2 is 0x68423fe8.
Which means that f[3][0][2] is 0x68423ffc.
- 8: f is 0x68423fe0.
That means that f+1 is 0x68423fe4.
Which means that f[1] is 0x68423fe0.
Which means that f[1]+1 is 0x68423fe4.
Which means that f[1][1] is 0x68423fe0.
Which means that f[1][1]+1 is 0x68423fe4.
Which means that f[1][1][1] is 0x68423fe0.
- 9: Pointer arithmetic, plain and simple -- 12 minus 10 equals 2: 0x2.
Grading
Three points for the first line. Two points for the others.
You got one point for answering 8 on line 9.
Question 5: 20 points
First, the size of Mystruct is 12 bytes. There are three bytes of padding after
b.
- 0: q is 0x61696f40, which means that &(q.b) is
also 0x61696f40. So q.b is 'n'.
- 1: &(q.s) is 0x61696f44, so q.s is
0x61696f66. When you print that with printf("%s", ..., it prints every
character from 0x61696f66, until it finds a null character. So the answer is 'iamoiaynh'.
- 2: &(q.i) is 0x61696f48, so q.i is 1728082432.
- 3: This is pointer arithmetic, so adding 3 to q add 36 to the pointer. In hex,
that's 0x24, so the new value of q is 0x61696f64. So, q.b is 'v'.
- 4: q.s is now 0x61696f6d, so the answer is 'nh'.
- 5: q.i is 6844025.
- 6: Since a is a (char *), adding 16 to it yields 0x61696f50.
So, &(q.s) is
0x61696f54 and q.s is 0x61696f5b. Printing that out is 'igoia'.
- 7: &(q.i) is 0x61696f58, so q.i is 1769631488.
- 8: q is now 0x61696f66. That's not aligned, but since we are only
accessing character q.b, the alignment doesn't matter. The answer is 'i'.
- 8: q[1] adds 12 to q: 0x61696f72. q.b is 'd'.
Here's the program running:
UNIX> q5 | tail -n 10
0: n
1: 'iamoiaynh'
2: 1728082432
3: v
4: 'nh'
5: 6844025
6: 'igoia'
7: 1769631488
8: i
9: d
UNIX>
Grading
- Two points per line.
- One point for 'foia' on line 1.
- One point for 'moiaynh' on line 4.
- One point for '[oia' on line 6.