CSE 351 Midterm Exam Solutions - Winter 2018, Exams of Programming Languages

Question 3: C Programming & x86-64 Assembly [20 pts.] Consider the following x86-64 assembly and (mostly blank) C code. The C code is in a file ...

Typology: Exams

2022/2023

Uploaded on 05/11/2023

aghanashin
aghanashin 🇺🇸

4.7

(22)

253 documents

1 / 10

Toggle sidebar

This page cannot be seen from the preview

Don't miss anything!

bg1
University of Washington Computer Science & Engineering
Winter 2018 Instructor: Mark Wyse February 5, 2018
1
CSE 351 Midterm Exam
Last Name:
SOLUTIONS
First Name:
UW Student ID Number:
UW NetID (username):
Academic Integrity Statement:
All work on this exam is my own. I had no prior knowledge of
the exam contents, nor will I share the contents with others in
CSE 351 who haven’t taken it yet. Violation of these terms may
result in a failing grade. (please sign)
Do not turn the page until 11:30 am.
Instructions
This exam contains 10 pages, including this cover page, and 2 reference pages.
Show scratch work for partial credit but answer in the blanks and boxes provided.
The last page is a reference sheet. Please detach it from the rest of the exam.
This exam is closed book and closed notes (no laptops, tablets, smartphones, wearable devices,
or calculators).
Please silence/turn-off all cell phones, mobile devices, or other noise-making devices. Remove all
hats, headphones, and watches.
You have 50 minutes to complete this exam.
Advice
Read each question carefully.
Read all questions first and start where you feel most confident.
Relax and breathe; you are here to learn.
Question
1
2
3
4
5
Total
Points Possible
20
14
20
24
10
88
Points Earned
pf3
pf4
pf5
pf8
pf9
pfa

Partial preview of the text

Download CSE 351 Midterm Exam Solutions - Winter 2018 and more Exams Programming Languages in PDF only on Docsity!

University of Washington – Computer Science & Engineering

Winter 2018 Instructor: Mark Wyse February 5, 2018

CSE 351 Midterm Exam

Last Name: (^) SOLUTIONS First Name: UW Student ID Number: UW NetID (username): Academic Integrity Statement: All work on this exam is my own. I had no prior knowledge of the exam contents, nor will I share the contents with others in CSE 351 who haven’t taken it yet. Violation of these terms may result in a failing grade. ( please sign ) Do not turn the page until 11:30 am. Instructions

  • This exam contains 10 pages, including this cover page, and 2 reference pages.
  • Show scratch work for partial credit but answer in the blanks and boxes provided.
  • The last page is a reference sheet. Please detach it from the rest of the exam.
  • This exam is closed book and closed notes (no laptops, tablets, smartphones, wearable devices, or calculators).
  • Please silence/turn-off all cell phones, mobile devices, or other noise-making devices. Remove all hats, headphones, and watches.
  • You have 50 minutes to complete this exam. Advice
  • Read each question carefully.
  • Read all questions first and start where you feel most confident.
  • Relax and breathe; you are here to learn. Question 1 2 3 4 5 Total Points Possible 20 14 20 24 10 88 Points Earned

Question 1: Number Representation [20 pts.] (A) Complete the following table, assuming an 8 - bit, Two’s Complement representation. Remember to use the appropriate bit widths for the hex and binary columns. [6 pts.] Decimal (base 10) Hexadecimal (base 16) Binary 1 0x 01 0b 0000 0001 103 0x 67 0b 0110 0111

- 39 0x D9 0b 1101 1001 38 0x 26 0b 0010 0110 (B) Consider the table below where each row contains two 8-bit integral constants that will be compared using the < , > , or == comparison. Determine which comparison makes the expression: Left Constant ( <, >, == ) Right Constant evaluate to True. Also state the type of comparison that is performed ( signed or unsigned ) assuming we use the same type promotion and casting rules as C does. [8 pts.] Left Constant Order (<, >, ==) Right Constant Comparison Type 1 > 0 signed (int) 15U == 15 signed (unsigned) - 1 > - 2 unsigned (unsigned) - 128 > 127 unsigned 127 > (int) 128U signed (C) Given the 4-bit bit vector 0b110 1 , what is its value in decimal (base 10)? Circle your answer. [2 pts.] a. 13 b. - 3 c. - 5 d. Undefined. Need to specify if we want unsigned, sign & magnitude, two’s complement, etc. (D) In the C programming language, unsigned overflow is well defined. Circle your answer. [ 2 pts.] a. True b. False (E) In the C programming language, signed overflow is well defined. Circle your answer. [ 2 pts.] a. True b. False. C allows for a variety of signed integer representations, and thus signed overflow results in undefined behavior

Question 3: C Programming & x86-64 Assembly [20 pts.] Consider the following x86-64 assembly and (mostly blank) C code. The C code is in a file called foo.c and contains a main function and a mystery function, foo. The function foo takes one input and returns a single value. Fill in the missing C code that is equivalent to the x86-64 assembly for the function foo_. You can use the names of registers (without the %) for C variables._ [18 pts.] Hint : the function foo contains a for loop. There are more blank lines in the C Code than should be required for your solution. x86-64 Assembly: function foo C Code: file foo.c .text .globl foo .type foo, @function foo: jmp .L .L4: testb $1, %dil je .L movslq %edi, %rdx addq %rdx, %rax .L3: subl $3, %edi .L2: testl %edi, %edi jg .L ret #include <stdio.h> // for printf long foo( int x) { long sum; for (int i = x; i > 0; i = i- 3 ) { if (i & 0x1) { sum += i; } } return sum ; } Note: variable names may be different in students’ answers (e.g., use rax instead of sum). int main(int argc, char **argv) { long r = foo(10); printf(“r: %ld\n”, r); return 0; } Follow up: Assume the code in main is correct and has no errors. However, the provided x86- 64 code for function foo has a single correctness error. What is the error, and when might this error cause a problem with the execution of foo_? Answer in one or two short English sentences._ [2 pts.] The variable “sum” (or the variable we return from foo) is never initialized. Thus, it will hold a random value prior to the loop, and the execution of foo will always be incorrect (unless the variable happens to have the value 0 prior to loop execution).

Question 4: Procedures & The Stack [ 24 pts.] Consider the following x86-64 assembly and C code for the recursive function rfun. // Recursive function rfun long rfun(char s) { if (s) { long temp = (long)*s; s++; return temp + rfun(s); } return 0; } // Main Function - program entry int main(int argc, char **argv) { char *s = "CSE351"; long r = rfun(s); printf("r: %ld\n", r); } 00000000004005e6 : 4005e6: 0f b6 07 movzbl (%rdi),%eax 4005e9: 84 c0 test %al,%al 4005eb: 74 1 3 je 400600 <rfun+0x1a> 4005ed: 53 push %rbx 4005ee: 48 0f be d8 movsbq %al,%rbx 4005f2: 48 83 c7 01 add $0x1,%rdi 4005f6: e8 eb ff ff ff callq 4005e6 4005fb: 48 01 d8 add %rbx,%rax 4005fe: eb 06 jmp 400606 <rfun+0x20> 400600: b8 00 00 00 00 mov $0x0,%eax 400605: c3 retq 400606: 5b pop %rbx 400607: c3 retq

(F) Assume main calls rfun with char *s = “CSE351”, as shown in the C code. After main calls rfun, we find that the return address to main is stored on the stack at address 0x7fffffffdb38. On the first call to rfun, the register %rdi holds the address 0x4006d0, which is the address of the input string “CSE351” (i.e. char *s == 0x4006d0). Assume we stop execution prior to executing the movsbq instruction (address 0x4005ee) during the fourth call to rfun. [14 pts.] For each address in the stack diagram below, fill in both the value and a description of the entry. The value field should be a hex value, an expression involving the C code listed above (e.g., a variable name such as s or r , or an expression involving one of these), a literal value (integer constant, a string, a character, etc.), “unknown” if the value cannot be determined, or “unused” if the location is unused. The description field should be one of the following: “Return address”, “Saved %reg” (where reg is the name of a register), a short and descriptive comment, “unused” if the location is unused, or “unknown” if the value is unknown. Memory Address Value Description 0x7fffffffdb48 unknown %rsp when main is entered 0x7fffffffdb38 0x400616 Return address to main 0x7fffffffdb30 unknown original %rbx 0x7fffffffdb28 0x4005fb Return address 0x7fffffffdb20 *s, “C”, 0x 43 Saved %rbx 0x7fffffffdb18 0x4005fb Return address 0x7fffffffdb10 *s, *(s+1), “S”, 0x 53 Saved %rbx 0x7fffffffdb08 0x4005fb Return address 0x7fffffffdb0 0 *s, *(s+2), “E”, 0x45 Saved %rbx

Question 5: Fun Stuff [ 10 pts.] (A) Assume we are executing code on a machine that uses k-bit addresses, and each addressable memory location stores b-bytes. What is the total size of the addressable memory space on this machine? [2 pts.] (B) In C, who/what determines whether local variables are allocated on the stack or stored in registers? Circle your answer. [2 pts.] Programmer Compiler Language (C) Runtime Operating System (C) Assume procedure P calls procedure Q and P stores a value in register %rbp prior to calling Q. True or False: P can safely use the register %rbp after Q returns control to P. Circle your answer. [2 pts.] a. True. %rbp is a callee saved register. b. False (D) Assume we are implementing a new CPU that conforms to the x86-64 instruction set architecture (ISA). Answer the following questions, in one or two English sentences, regarding this new CPU. [4 pts.] a. In modern x86-64 CPUs, a new add operation can be executed every cycle. However, for our new CPU, we realize that we can save power by implementing the add operation such that we can execute a new add only once every three cycles. Is our new CPU still a valid x86- 64 implementation? Yes. The x86-64 architecture/specification says nothing about how fast any operation must execute in hardware. b. In our new CPU implementation, we decide to change the width of register %rsp to be 48- bits, since most modern x86-64 CPUs only use 48 - bit physical addresses, but we still use the name %rsp. Is our CPU still a valid x86-64 implementation? No. The x86-64 architecture/specification determines the number and size of registers available to the programmer/compiler. Changing this in our implementation violates the architecture. (2^k) * b

Conditionals Instruction Condition^ Codes^ (op) s, d^ test a, b^ cmp a, b je “Equal” ZF^ d^ (op)^ s^ ==^0 b^ &^ a^ ==^0 b^ ==^ a jne (^) “Not equal” ~ZF^ d^ (op)^ s^ !=^0 b^ &^ a^ !=^0 b^ !=^ a js “Sign” (negative) SF^ d^ (op)^ s^ <^0 b^ &^ a^ <^0 b-a^ <^0 jns (^) (non-negative) ~SF^ d^ (op)^ s^ >=^0 b^ &^ a^ >=^0 b-a^ >=^0 jg (^) “Greater” ~(SF^OF)^ &^ ~ZF^ d^ (op)^ s^ >^0 b^ &^ a^ >^0 b^ >^ a jge (^) “Greater or equal” ~(SF^OF)^ d^ (op)^ s^ >=^0 b^ &^ a^ >=^0 b^ >=^ a jl (^) “Less” (SF^OF)^ d^ (op)^ s^ <^0 b^ &^ a^ <^0 b^ <^ a jle (^) “Less or equal” (SF^OF)^ |^ ZF^ d^ (op)^ s^ <=^0 b^ &^ a^ <=^0 b^ <=^ a ja “Above” (unsigned >) ~CF^ &^ ~ZF^ d^ (op)^ s^ >^ 0U^ b^ &^ a^ <^ 0U^ b^ >^ a jb “Below” (unsigned <) CF^ d^ (op)^ s^ <^ 0U^ b^ &^ a^ >^ 0U^ b^ <^ a Registers Name of “virtual” register

Name Convention

Lowest 4 bytes Lowest 2 bytes Lowest byte %rax (^) Return value – Caller saved %eax %ax %al %rbx (^) Callee saved %ebx %bx %bl %rcx (^) Argument #4 – Caller saved %ecx %cx %cl %rdx (^) Argument #3 – Caller saved %edx %dx %dl %rsi (^) Argument #2 – Caller saved %esi %si %sil %rdi (^) Argument #1 – Caller saved %edi %di %dil %rsp (^) Stack Pointer %esp %sp %spl %rbp (^) Callee saved %ebp %bp %bpl %r8 (^) Argument #5 – Caller saved %r8d %r8w %r8b %r9 (^) Argument #6 – Caller saved %r9d %r9w %r9b %r10 (^) Caller saved %r10d %r10w %r10b %r11 (^) Caller saved %r11d %r11w %r11b %r12 (^) Callee saved %r12d %r12w %r12b %r13 (^) Callee saved %r13d %r13w %r13b %r14 (^) Callee saved %r14d %r14w %r14b %r15 (^) Callee saved %r15d %r15w %r15b Sizes C type x86- 64 suffix Size (bytes) char b 1 short w 2 int l 4 long q 8