Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Write your uniqname on the line provided at the top of each page.
You are to abide by the University of Michigan/Engineering honor code. Please sign below to
signify that you have kept the honor code pledge:
I have neither given nor received aid on this exam, nor have I concealed any violations of the
Honor Code.
Signature: _________________________________________
Name: _________________________________________
Uniqname: _________________________________________
First and last name of person sitting to your right (write the symbol if at the end of a row):
_________________________________________
First and last name of person sitting to your left (write the symbol if at the end of a row):
_________________________________________
uniqname: ______________________
1) How many different memory locations can you access with an 8-bit memory address?
2) What does the terminal output when the following code is executed?
int a = 0b01001011;
a = (a >> 3) & 0x7;
printf(%d\n, a);
Answer: _________1_____________
Expressions that evaluate to 1 but are not 1 (ex. 0x1, 0b001) were not accepted.
3) The value 0x0EEC5370 is stored at memory addresses 100-103. What is the value
stored in r3 after this line of ARM assembly code executes, assuming little endian
format? (Assume r0 contains the value 0.)
4) Convert the number 2.25 to floating point. Write your answer in hex.
5) Which of the following is/are true of register files? Circle all that apply.
5)c) was not assigned any points during grading due to the ambiguity between memory
meaning main memory vs. cache memory. Had the question said main memory, c) should have
been circled.
uniqname: ______________________
8) For the same size of physical memory, a word-addressable system would have the
same number of distinct addresses as a byte-addressable system.
True False
9) Consider the following piece of code. Circle whether each variable goes on the stack,
heap, static, or text segment of memory. Assume function parameters are not loaded in
registers.
char *boo;
static int g = 1;
void foo(int* f) {
static char w = 2;
int y = 3;
void (*bar)(int*);
bar = &foo;
boo = (char*)malloc(4);
}
struct Student;
struct Course {
struct Student* roster[700];
char* name;
};
lice
a) Fill in the blanks above to indicate the range of memory that each variable in a
occupies. Provide your answer in decimal.
b) Reorder the member variables in s truct Student to minimize the size, indicating each
members position by a number from 1 to 6 on the given lines.
Many possible solutions, but here are some:
struct Student {
2/3/4 3/4 int umid;
1 2 double gpa;
5 5 short num_courses;
2/3/4 3/4 int num_credits;
6 6 char permissions;
2/3/4 1 struct Course* courses[MAX_COURSES];
};
c) How many bytes of memory would a lice occupy using this new definition of s
truct
Student?
____48____ bytes
uniqname: ______________________
Convert the C function whoWon() to ARM assembly by filling in the blanks. Assume that all
registers are caller-saved, that function parameters are passed through registers r0 and r1, and
that the function returns a value through r0. All immediates should be expressed in
hexadecimal.
C Source Code
struct Contender {
char name[10];
short score1; // Scores can be negative
int scoreFinal;
};
int whoWon(struct Contender contenders[], int size){
int total = 0, maxScore = 0x80000000, maxScoreIndex = 0, i = 0;
for(i = 0; i < size; ++i){
total = contenders[i].score1 + contenders[i].scoreFinal;
if(total >= maxScore){
maxScore = total;
maxScoreIndex = i;
}
}
return maxScoreIndex;
}
ARM Assembly
bx r14 // return
uniqname: ______________________
1. For the code above, fill in the final state of the registers and memory. (Assume big-endian)
In this question, you will explore writing a simple LC2K assembly program to search an array of
integers.
int main()
{
int arr[7];
LC2K_linear_search(arr, 7, 53);
return 0;
}
if (i == size)
return -1;
return i;
}
a) Here is the above call to LC2K_linear_search after it has been compiled into LC2K
assembly code. Fill in the blanks to complete the implementation.
lw 0 1 one
add 0 0 2
lw 0 3 size
lw 0 4 num
lw 0 5 loop
jalr 5 6
end halt
loop beq 2 3 done
lw 2 5 arr
beq 5 4 done
add 1 2 2
beq 0 0 loop
done beq 2 3 error
add 0 2 7
beq 0 0 return
error lw 0 7 neg1
return jalr 6 5
one .fill 1
neg1 .fill -1
num .fill 53
size .fill 7
arr .fill 54
.fill 8
.fill 43
.fill 0
.fill 20
.fill 33
.fill 37
.fill 53
.fill 30
C2K_linear_search ? __7____
b) How many times does the for loop execute in this call to L
void foo(void) {
int r1 = 0, r2 = 0, r3 = 0;
int r4 = 5;
r2 = r1 + r3 + r4;
bar();
for(; r2 != 0; r2--) {
}
r4 = r3;
bar();
}
void bar(void) {
int r5 = 0, r6 = 0;
for(; r5 < 5; r5++) {
}
uniqname: ______________________
Consider the C code on the previous page. Assume all variables are mapped to registers of the
same name. Only consider the loads and stores executed within the functions f oo() and bar().
Assume the only analysis the compiler can perform is liveness analysis.
A. First consider the case where all the registers are c aller saved, how many load/store
instruction pairs would be executed by the program if foo is called once? Then consider the
case where all registers are callee saved, how many load/store instruction pairs would be
executed by the program if foo is called once? Fill in the number of loads/stores in the table
below.
// 1 point per register, 12 total points for this part
Register # of Caller Load/Store Pairs Executed # of Callee Load/Store Pairs Executed
r1 1 1
r2 6 1
r3 7 1
r4 1 1
r5 10 2
r6 0 2
// 2 points for the correct answer, dependent on the answer for part A
b) What is the total number of load/store instructions executed when each of the variables are
optimally assigned to either caller or callee registers?
Note: the #include <stdlib.h> at the top of osify.c allows that file to call functions malloc and free
defined elsewhere. Assume that every access to globals or values pointed to by globals must go
to memory.
main.c osify.c
int eecs370 = 370; 0: #include <stdlib.h>
extern double* eecs470; 1:
extern void no_time(); 2: double* eecs470;
extern void happier_days(); 3:
int level_up(); 4: void no_time(){
5: eecs470 = (double*) malloc(8);
int main() { 6: }
no_time(); 7:
eecs370 += 100; 8: void happier_days(double num) {
*eecs470 = (double) levelup(); 9: double eecs482 = num + 12;
happier_days(*eecs470); 10: free(eecs470);
return 0; 11: }
} 12:
13:
int level_up(){ 14:
return eecs370; 15:
} 16:
17:
18:
Fill out each object files data section. If a value isnt initialized, write N/A.
main.o Data Section osify.o Data Section
Name Initialized Value Name Initialized Value
eecs370 370 eecs470 N/A
uniqname: ______________________
For the following symbol tables, put the name of the symbol, and mark the type as T, D or U
depending on whether that symbol is in the Text or Data section or Undefined. If the symbol is
defined, put at which line it is defined in the c source file. Leave it blank otherwise.
Fill out each object files relocation table, with a line number that needs to be fixed up, the
instruction type (bl, str, or ldr), and the symbol that instruction is dependent on.
After listening to feedback from loyal customers, Team EECS370 decided to upgrade LC2K to a
byte-addressable CISC architecture that supports up to 16 registers. Additionally, some of the
opcodes have been changed. The changes are summarized as follows:
Due to the CISC upgrade, instructions now have variable lengths (ie. 16-bit or 32-bit).
Due to byte-addressability, the PC is now incremented by 2 or 4 at the end of every
instruction based on the type of next instruction
beq branches to address PC + 4 + 2*offset, and jalr stores P C + 2 to regB.
lw has been replaced with m ov, which sets regA equal to an 8-bit signed offset
sw has been replaced with s wp, which swaps the content of [regB] with the value stored
at memory address M[[regA] + offset]. In a sense, this is a combined lw and sw.
All unspecified opcodes remain the same. However, instructions are now encoded differently
(due to the variable instruction lengths), as shown below. Note that unused bits are coded as 0.
You may also use this table as a quick reference for CISC LC-2K (changes are highlighted):
swp 011 I-Type Swap the value of regB with the value in MEM[ regA + 16-bit offset
]
jalr 101 J-Type Store (PC+2) into regB, then jump to regA.
a) Convert the following code snippet into machine code using CISC LC-2K. Assume file starts
xpress your answers in hexadecimal.
from address 0, and .fill still uses 32-bit integers. E
b) How much memory does the above machine code occupy in bytes (including the .fill)?
14 bytes
c) How can the processor tell if a machine-code instruction is 16 bits or 32 bits long? (Express
your answer in one sentence.)
d) Below is an incomplete CISC LC-2K assembly program that shuffles the position of 50
integers. The integers start at memory address 100. The program iterates through each
position, and swaps it with another random position, determined by the output of a function
called RNG. The function RNG takes in no inputs, and returns an integer between 1 and 50
through reg3. Assume all registers are initialized to 0.
Complete this CISC LC-2K code by filling in the blanks. Assume that RNG does not touch any
other registers, so you dont need to caller/callee save anything.
mov 2 50
add 1 1 5
add 5 5 5 # reg5 = 4 * i
add 3 3 3
add 3 3 3 # reg3 *= 4
add 1 5 1 # increment i
beq 0 0 loop
end halt