Compiling code that accesses an element of an array involves computing the base address of the array and the offset from that address to the specified element. The offset to array elements can sometimes be computed statically.
Assume the following declaration (in C) of variable a.
int* a = (int[]) { 32, 24, 38, 21, 17, 12 };
Note that the syntax given above is available in modern C compilers, and is conceptually the same as the following, but more concise:
int* a = malloc(6 * sizeof(int));
a[0] = 32;
a[1] = 24;
a[2] = 38;
a[3] = 21;
a[4] = 17;
a[5] = 12;
For each of the following C expressions match with the value of the expression. If the expression is invalid, or the information provided is insufficient to compute the value, keep the value blank, and select the appropriate option.
&a[5] - &a[1]
Evaluates to 4
&a[10] - &a[5]
Evaluates to 5
&(*(a+(*(a+5)-11)))-&a[1]
a+5 // &a[5]
*(a+5) // 12
*(a+5) - 11 // 1
a+(*(a+5)-11) // &a[1]
*(a+(*(a+5)-11)) // 24
&(*(a+(*(a+5)-11)))-&a[1] // 0
Evaluates to 0
Consider an array named a in C with the values { 15, 16, 17, 18, 19 } (the array may have additional unknown values, but these are the values at the start of the array). Consider a variable named i of type intĀ *, that points to the start of array a. Assume that i is stored at address 0x3200, and that a is stored at address 0x4600.
For each of the following C expressions match with the value of the expression. If the expression is invalid, or the information provided is insufficient to compute the value, keep the value blank, and select the appropriate option.
&i[0]:
Evaluates to 0x4600
i:
Evaluates to 0x4600
*i:
Evaluates to 15
*(i+1):
Evaluates to 16
*(i+9):
Consider the following C global variable declarations.`
int a, b, c, *d, **e, f[10], *g[10], **h[10];
For the C statement below, indicate the total number of memory locations accessed (i.e. read and/or written) when it executes. Do not count the loading of the instruction itself. Assume that nothing useful is stored in any register before the statement executes.
a = &b - &a;
.pos 0x100
ld $a, r1
ld (r1), r1
ld $1,r2
ld (r1,r2,4), r2
ld (r1,r2,4), r3
halt
.pos 0x1000
a: .long 0x2000
b: .long 0x2004
.pos 0x2000
.long 0x6
.long 0x5
.long 0x2
.long 0x4
.long 0x3
.long 0x5
.long 0x5
.long 0x2
.long 0x6
r3 after the Program Executes?ld $a, r1 # &a ld (r1), r1 # a ld $1,r2 # 1 ld (r1,r2,4), r2 # a[1] -> 0x5 ld (r1,r2,4), r3 # a[5] -> 0x5
r3=0x5
ld $a, r1 Was Changed to ld $b, r1, what Would Be the Value in R3 after the Program Executes?ld $a, r1 # &b ld (r1), r1 # b <-> &a[1] ld $1,r2 # 1 ld (r1,r2,4), r2 # b[1] -> 0x2 ld (r1,r2,4), r3 # b[3] -> 0x4
r3=0x4
Consider the following C global variable declaration.
int a;
int b[15];
int *c;
int **d;
Translate the following C statements into assembly language.
Pointers are 4-bytes long.
Use labels to refer to the memory address of each variable. Assume that these labels have already been defined; i.e., do not include their definition in your answer. Also, do not include any assembly directives such as .pos or .long.
You may add comments if it helps you (using the standard notation # comment), but doing so is not required.
Translate this C code
b[a] = c[a];
Into SM213 Assembly code
ld $a, r0 # &a
ld (r0), r1 # a
ld $c, r2 # &c
ld (r2), r3 # c
ld (r3, r1, 4), r4 # c[a]
ld $b, r5 # &b
ld (r5), r6 # b
st r4, (r5, r1, 4) # b[a] = c[a]
In this question you will analyze the execution of three short blocks of code based on a common set of variable declarations and initializations. This common code is included with each subquestion for convenience, but it is the same for every subquestion. Treat each subquestion separately; that is, each one starts from scratch from the initialized values of the variables.
For each question, give the following three values for the last line of each code block following the execution of the entire block:
If you cannot determine the memory address from the information given, enter 0 for the address.
When computing the number of distinct locations read, assume nothing about the value of registers prior to the execution of the last statement: count a location even if the previous line also read (or wrote) that location. If the line reads from a memory location multiple times, count it only once. Assume that memory accesses always succeed, i.e. that all memory addresses are accessible to the program.
For example, for the following code block:
int *foo = (int *)0x1000;
int *bar = (int *)0x1000;
*foo = 1;
*foo = *foo + *bar + 1;
you would answer address = 0x1000, value = 3 and locations = 3 (one for foo, one for bar, and one for what they point to).
Give memory addresses in hex; and values and location counts in decimal.
// Declarations and Initializations --- THE SAME FOR EVERY SUBQUESTION
int *i = (int *)0x7000;
int *p = (int *)0x7004;
int *t = (int *)0x7008;
int *y = (int *)0x700c;
int *z = (int *)0x6000;
int **b = (int **)0x9000;
int **k = &p;
int **s = &i;
int **u = &t;
int **w = &y;
*i = 20;
*p = 4;
*t = 20;
*y = 19;
// set b[0] ... b[9] = [&z[0], &z[1], ... , &z[9]]
// set z[0] ... z[9] = [7, 3, 8, 9, 1, 4, 6, 5, 2, 0]
// Unique Code for this Subquestion
t = p;
*t = *y + *t;
0x7004// Unique Code for this Subquestion
*y = *(z + 4);
b[*y] = *b + 6;
*b[*y] = *b[*y] + z[*y] + (&z[5] - &z[4]);
0x6018