These problems should be done on your own. We're not going to be grading them strictly (we'll mainly look at whether you attempted them). But they will be reinforcing knowledge and skills, so you should totally work through them carefully.
Stack frames
In the following code snippet, where comments indicate line numbers:
uint64_t x = 2;
uint64_t y = 5;
uint64_t mul(uint64_t a, uint64_t b) {
uint64_t e = a * b; // L0
return e; // L1
}
uint64_t comp(uint64_t n) {
uint64_t e = 0; // L2
uint64_t f = 0; // L3
e = mul(x, n); // L4
f = mul(n, y); // L5
return e + f; // L6
}
int main() {
comp(2); // L7
}
Draw the stack, and show where the base pointer (%rbp) and the stack pointer (%rsp) point right before L4 begins executing.
Draw the stack, and show where the base pointer (%rbp) and the stack pointer (%rsp) point right before the
call
instruction that transfers control to themul
function is executed (that is, after arguments have been placed in the appropriate registers). What line of source code does the instruction pointer (%rip) correspond to in this case? Note that some lines of C can expand into multiple instructions; your answer should specify the line of C code that led to the compiler producing the instruction at the address pointed to by %rip.Draw the stack right after mul’s prologue has finished executing. You can assume that mul was called from L4.
Draw the stack right after mul’s epilogue has finished executing, but before the
ret
instruction has returned control to the caller. Also state what line of C source code the instruction pointer (%rip) corresponds to in this case. You should assume that mul was called from line L4. Similar to part (b), your answer should specify the line of C that led to the instruction pointed to by %rip being produced.
Linked lists
This question will provide some practice with linked lists (you may thank us during job interview season: linked lists are common subjects of interview questions).
In the code below, we specify a data structure node_t
:
struct node_t {
int id;
char name[10];
struct node_t *next;
};
A linked list consists of a list of these structures, connected via the next
field, which is a pointer to another node_t
. Given the head of a linked list (a pointer to the first element), the program can traverse the linked list by following the next
pointers (you will do that in the exercise below). The last element in a linked list (assuming the list has been set up correctly) has its next
field set to NULL.
We wish to write code that stores a list of students, each with an id
and a name
. We also will arrange to keep all elements keep sorted by student ids. The skeleton is below. You will fill it in.
/* Iterate through the sorted list (by node_t::id), and find the position after
* which the new 'node' should be inserted in the list. Ensure that the list
* is kept sorted. Return the element just before the newly inserted one.
* If the new 'node' should be inserted at the beginning, return NULL.
*/
node_t *
find_insert_pos(node_t *head, node_t *node)
{
if (head == NULL) return NULL;
node_t *ret = NULL;
// 2.1 your code here
return ret;
}
/* insert a new 'node' into the list 'head', return the new head of the list.
node_t *
insert(node_t *head, node_t *node)
{
if (head == NULL) return node;
// find the proper position to insert this node pair.
node_t *pos = find_insert_pos(head, node);
// 2.2 your code here
return head;
}
int
main(void)
{
node_t *student_list = NULL;
// init first student Alice
node_t *student_1 = (node_t *)malloc(sizeof(node_t));
student_1->id = 1002;
strcpy(student_1->name, "Alice");
student_1->next = NULL;
// init second student Bob
node_t *student_2 = (node_t *)malloc(sizeof(node_t));
student_2->id = 1000;
strcpy(student_2->name, "Bob");
student_2->next = NULL;
student_list = list_insert(student_list, student_1);
student_list = list_insert(student_list, student_2);
// now we should have a student list:
// <1000, Bob> -> <10002, Alice> -> NULL
... free resources ...
return 0;
}
- Traverse the list; return the insertion position.
- Insert
node
in the listhead
; make sure the return value is correct.
Shell
State the output (or behavior) of each of the following commands.
i. echo echo hello $world ii. echo 'echo hello $world' iii. echo "echo hello $world" iv. echo `echo hello $world` v. echo (echo hello $world)
i. echo 'hello world' | cat ii. echo 'hello world' > cat iii. echo 'hello world' 2> cat
i. echo a && echo b ii. echo a ; echo b iii. echo a & echo b
There is a file 'members.txt'. Assume it is in the following form:
Name:John
NetId:j22
email:john@nyu.edu
Name:Amy
NetId:a123
email:amy@nyu.edu
...
Try to use a pipeline (a shell command that uses a pipe) for each of the following tasks:
To output the first 100 names in this file. (Hint: you may want to compose the following commands: grep "^Name:[a-zA-Z']\+$", head -n100, cut -d':' -f 2)
To identify the first 100 names by alphabetical order, and then (in one command) output them (as above) and write them to a file called 'names.txt'. (Hint: you may want to use: sort, tee names.txt.)
Handing in the homework
Use Gradescope; you can enroll in our course with entry code JBGJKG. (And please feel free to send us feedback about Gradescope.)