CS 208 s21 — Review Worksheet

Table of Contents

1 Number Representation

Consider the binary value 0b110101:

  1. Interpreting this value as an unsigned 6-bit integer, what is its value in decimal?




  2. If we instead interpret it as a signed (two's complement) 6-bit integer, what would its value be in decimal?




  3. Assuming these are all signed two's complement 6-bit integers, compute the result (leaving it in binary is fine) of each of the following additions. For each, indicate if it resulted in overflow.
  0 0 1 0 0 1
+ 1 1 0 1 1 0
Result:            

Overflow?


  1 1 0 0 0 1
+ 1 1 1 0 1 1
Result:            

Overflow?


  0 1 1 0 0 1
+ 0 0 1 1 0 0
Result:            

Overflow?


  1 0 1 1 1 1
+ 0 1 1 1 1 1
Result:            

Overflow?

2 Bitwise

bitwise-ops.png

  1. What happens when we fix/set one of the inputs to the 2-input operators? Let x be the other 1-bit input. Fill in the following blanks with either 0, 1, x, or NOT x:
    • x & 0 =
    • x & 1 =
    • x | 0 =
    • x | 1 =
    • x ^ 0 =
    • x ^ 1 =
  2. Bit Extraction: Returns the value (0 or 1) of the 19th bit (counting from LSB). Use >> and &.
    int extract19(int x) {
        return ____________________________________________________________;
    }
    

3 Pointers

For this problem we are using a 64-bit x86-64 machine (little endian). The current state of memory (values in hex) is shown below:

review-mem-grid.png

Write the value in hexadecimal of each expression within the commented lines at their respective state in the execution of the given program. Write UNKNOWN in the blank if the value cannot be determined.

int main() {
    char *charP;
    short *shortP;
    int *intP = 0x00;
    long *longP = 0x28;

    // The value of intP is:                   0x_____________________________

    // *intP                                   0x_____________________________

    // &intP                                   0x_____________________________

    // longP[-2]                               0x_____________________________

    charP = 0x20;
    shortP = (short *) intP;
    intP++;
    longP--;

    // *shortP                                 0x_____________________________

    // *intP                                   0x_____________________________

    // *((int*) longP)                         0x_____________________________

    // (short*) (((long*) charP) - 2)          0x_____________________________
}

4 Assembly

  1. Write an English description for each of the following instructions:
    x86 instruction English equivalent
    movq $351, %rax Move the number 351 into 8-byte (quad) register "rax"
    addq %rdi, %rsi  
    movq (%rdi), %r8  
    leaq (%rax,%rax,8), %rax  
  2. Consider the following x86-64, (partially blank) C code, and memory diagram. Addresses and values are 64-bit. Fill in the C code based on the given assembly.
    foo:
        movl $0, %eax
    L1:
        testq %rdi, %rdi
        je L2
        movq (%rdi), %rdi
        addl $1, %eax
        jmp L1
    L2:
        ret
    
    int foo(long* p) {
        int result = ____;
        while (________) {
            p = ___________;
            _____ = __________;
        }
        return result;
    }
    
  3. Follow the execution of foo in assembly, where 0x1000 is passed in to %rdi. Write the values of %rdi and %eax in the columns. If the value doesn't change, you can leave it blank. Continue writing the next instruction and any changed values until you have traced the full execution (i.e., reached ret).
    instruction %rdi (in hex) %eax (decimal)
    movl 0x1000 0
    testq    
    je    
         
         
         
         
         
         
         
         
         
         
address value
0x1000 0x1030
0x1008 0x1020
0x1010 0x1000
0x1018 0x0000
0x1020 0x1030
0x1028 0x1008
0x1030 0x0000
0x1038 0x1038
0x1040 0x1048
0x1048 0x1040