






Study with the several resources on Docsity
Earn points by helping other students or get them with a premium plan
Prepare for your exams
Study with the several resources on Docsity
Earn points to download
Earn points by helping other students or get them with a premium plan
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
1 / 10
This page cannot be seen from the preview
Don't miss anything!







Winter 2018 Instructor: Mark Wyse February 5, 2018
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
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
(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
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