程序代写 assembly Name:

Name:
ID#: X.500:
Problem 1 (15 pts):
Nearby is a C function col update()
1 typedef struct{ 2 int cur;
3 int step;
4 } colinfo_t;
5 // | | Byte | Byte | Packed | 6 //|Field|Size|Offset| Bits| 7 // |——-+——+——–+——–| 8 // | cur | 4 | +0 | 0-31 | 9 // | step | 4 | +4 | 32-64 |
CS 2021: Practice Exam 2 SOLUTION
Fall 2021 University of Minnesota
Exam period: 20 minutes Points available: 40
with associated data and documentation. Re-implement
this function in x86-64 assembly according to the doc-
umentation given. Follow the same flow provided in the C
implementation. The comments below the colinfo t struct
give information about how it lays out in memory and as a
packed argument.
Indicate which registers correspond to which C vari- 10
ables.
### SOLUTION:
.text
.globl col_update
# YOUR CODE BELOW
col_update:
movl 0(%rdi),%esi
movl 4(%rdi),%edx
cmpl $0,%esi
jle .ERROR
addl $1,%edx
testl $0x01,%esi
jz .EVEN
## ODD CASE (fall through)
imull $3,%esi
addl $1,%esi
jmp .RETURN
.EVEN:
sarl $1,%esi
.RETURN:
movl %esi,0(%rdi)
movl %edx,4(%rdi)
movl $0,%eax
ret
movl $1,%eax
ret
# cur = info->cur
# step= info->step
# if(cur < 0) # step++ # if(cur%2 == 1) # go to even case #odd:cur*=3 #odd:cur+=1 # jump over even #even:cur/=2 # info->cur = cur;
# info->step= step;
# success
# return 0
# error case
# return 1
11 int col_update(colinfo_t *info){
12 // Updates current value and step in
13 // colinfo_t pointed by param info. If
14 // infor->cur is invalid, makes no changes 15 // and returns 1 to indicate an
16 // error. Otherwise performs odd or even 17 // update on cur and increments step
18 // returning 0 for success.
19
20 int cur = info->cur;
21 int step = info->step;
22 if(cur <= 0){ 23 return 1; 24 } 25 step++; 26 if(cur % 2 == 1){ 27 cur = cur*3+1; 28 } 29 else{ 30 cur = cur / 2; 31 } 32 info->cur = cur;
33 info->step = step;
34 return 0;
35 }
.ERROR:
1/ 2

WRITE ON EVERY PAGE – Name: SOLUTION
Problem 2 (15 pts): Below is an initial register/memory configuration along with snippets of assembly code. Each snippet is followed by a blank register/memory configuration which should be filled in with the values to reflect changes made by the preceding assembly. The code is continuous so that POS A is followed by POS B.
SOLUTION:
INITIAL |——-+——-| | REG | Value | |——-+——-| |rax|10| |rdi|20| |rsi | 30| | rsp | #3032 | |——-+——-| | MEM | Value | |——-+——-| | #3032 | 250 | |#3028| 1| |#3024| 2| |#3020| 3| |——-+——-|
addl %edi, %esi
subq $8, %rsp movq $1, %rdi
movl $100, 4(%rsp) addl %esi, (%rsp,%rdi,4)
movl $300, 0(%rsp) leaq 8(%rsp), %rdi
Problem 3 (10 pts): Rover Witer is writing an as- 1
sembly function called compval which he will use in C
programs. He writes a short C main() function to test
compval but is shocked by the results which seem to defy 5
the C and assembly code. Valgrind provides no insight for him. Identify why Rover’s code is behaving so strangely and fix compval so it behaves correctly.
Sample Compile / Run:
> gcc compval_main.c compval_asm.s
> a.out
expect: 0
actual: 19
expect: 0
actual: 50
// compute something based on x and y
6 // store result at int pointed to by val 7
8 int main(){
SOLUTION: The movq instruction at line 7 of compval 20 21 writes 8 bytes. This is inappropriate as a 4-byte int is sup- 22
posed to be written. Apparently the stack layout in main() has the variable actual at a memory address immediately below variable expect so that on writing 8 bytes, the low
order 4 bytes correctly get written to actual but the high 4
5 6 7
compval_asm_corrected.s
order 4 bytes (all 0’s for small values) overwrite the vari- able expect leaving it as 0. The fix for this is to use movl %eax, (%rdx) which will write 4 bytes, filling only 8 actual.
compval:
imulq %rdi,%rsi
addq $5,%rsi
movl %esi,(%rdx) # was movq %rsi, (%rdx)
ret # now fixed
addl (%rsp), %eax #POSA |——-+——-| | REG | Value | |——-+——-| |rax | 310| |rdi|20| |rsi | 50| | rsp | #3024 | |——-+——-| | MEM | Value | |——-+——-|
addl (%rdi), %rax # POS B |——-+——-| | REG | Value | |——-+——-| |rax | 560| | rdi | #3032 | |rsi | 50| | rsp | #3024 | |——-+——-| | MEM | Value | |——-+——-|
| #3032 |
| #3028 |
| #3024 |
| #3020 |
|——-+——-|
| #3032 |
| #3028 |
| #3024 | |#3020| 3| |——-+——-|
250 |
100 |
300 |
250 |
150 |
300 |
3|
9 10 11 12 13 14 15 16 17 18 19
int expect, actual;
expect = 7 * 2 + 5;
compval(7, 2, &actual); // actual result
printf(“expect: %d\n”,expect);
printf(“actual: %d\n”,actual);
expect = 5 * 9 + 5; // expected value
compval(5, 9, &actual); // actual result
printf(“expect: %d\n”,expect);
printf(“actual: %d\n”,actual);
return 0; }
// compval_main.c
2 #include
3
4 void compval(int x, int y, int *val);
1 #
2 .text
3 .global compval
// expected value
2/ 2