Assume the following values are stored at the indicated memory addresses and registers:
Address | Value | Register | Value |
---|---|---|---|
0x100 | 0xFF | %eax | 0x100 |
0x104 | 0xAB | %ecx | 0x1 |
0x108 | 0x13 | %edx | 0x3 |
0x10C | 0x11 |
Fill in the following table showing the values for the indicated operands
Operand | Value |
---|---|
%eax | |
0x104 | |
$0x108 | |
(%eax) | |
4(%eax) | |
9(%eax,%edx) | |
260(%ecx,%edx) | |
0xFC(,%ecx,4) | |
(%eax,%edx,4) |
src_t v; dest_t *p; *p = (dest_t) v;
Assume
v stored in appropriate part of %eax (%eax, %ax, or %al) p stored in %edx
src_t | dest_t | Instruction |
---|---|---|
int | int | movl %eax, (%edx) |
char | int | |
char | unsigned | |
unsigned char | int | |
int | char | |
unsigned | unsigned char | |
unsigned | int |
You are given the following information. A function with prototype
void decode1(int *xp, int *yp, int *zp);
is compiled into assembly code. The body of the code is as follows:
1 movl 8(%ebp),%edi 2 movl 12(%ebp),%ebx 3 movl 16(%ebp),%esi 4 movl (%edi),%eax 5 movl (%ebx),%edx 6 movl (%esi),%ecx 7 movl %eax,(%ebx) 8 movl %edx,(%esi) 9 movl %ecx,(%edi)
Parameters xp, yp, and zp are stored at memory locations with offsets 8, 12, and 16, respectively, relative to the address in register %ebp.
Write C code for decode1 that will have an effect equivalent to the assembly code above.
You can test your answer by compiling your code with the -S switch. Your compiler may generate code that differs in the usage of registers or the ordering of memory references, but it should still be functionally equivalent.
Suppose register %eax holds value x and %ecx holds value y. Fill in the table below with formulas indicating the value that will be stored in register %edx for each of the following assembly code instructions.
Expression | Result |
---|---|
leal 6(%eax), %edx | |
leal (%eax,%ecx), %edx | |
leal (%eax,%ecx,4), %edx | |
leal 7(%eax,%eax,8), %edx | |
leal 0xA(,$ecx,4), %edx | |
leal 9(%eax,%ecx,2), %edx |
Assume the following values are stored at the indicated memory addresses and registers:
Address | Value | Register | Value |
---|---|---|---|
0x100 | 0xFF | %eax | 0x100 |
0x104 | 0xAB | %ecx | 0x1 |
0x108 | 0x13 | %edx | 0x3 |
0x10C | 0x11 |
Fill in the following table showing the effects of the following instructions, both in terms of the register or memory location that will be updated and the resulting value.
Instruction | Destination | Value |
---|---|---|
addl %ecx,(%eax) | ||
subl %edx,4(%eax) | ||
imull $16,(%eax,%edx,4) | ||
incl 8(%eax) | ||
decl %ecx | ||
subl %edx,%eax |
The shift arithmetic right instruction is
sarl k, x ; x = x >> k
But note: k should be a value 0 to 31 and must be either an immediate value or the register %cl (lower order byte of %ecx).
Practice Problem 3.8: Suppose we want to generate assembly code for the following C function: int shift_left2_rightn(int x, int n) { x <<= 2; x >>= n; return x; }
The following is a portion of the assembly code that performs the actual shifts and leaves the final value in register %eax.
Two key instructions have been omitted. Parameters x and n are stored at memory locations with offsets 8 and 12, respectively, relative to the address in register %ebp.
1 movl 12(%ebp),%ecx ; Get x 2 movl 8(%ebp),%eax ; Get n 3 _____________ ; x <<= 2 4 _____________ ; x >>= n
Fill in the missing instructions, following the annotations on the right. The right shift should be performed arithmetically.
1 2 #define MAXLINE 130 3 4 void usage(); 5 void phase_1(char s[]); 6 7 int main(int argc, char* argv[]) 8 { 9 char line[MAXLINE]; 10 FILE *in; 11 if (argc > 1) { 12 in = fopen(argv[1], "r"); 13 if (in == NULL) { 14 usage(); 15 } 16 } else { 17 in = stdin; 18 } 19 fgets(line, MAXLINE, in); 20 phase_1(line); 21 printf("You are a winner!! You have earned a chance for 0.1 extra 22 points\n"); 23 return 0; 24 } 25 26 void usage() 27 { 28 printf("\nUsage: whatinput1 [inputfile]\n"); 29 exit(0); 30 }
08048568 <phase_1>: 8048568: 55 push %ebp 8048569: 89 e5 mov %esp,%ebp 804856b: 83 ec 38 sub $0x38,%esp 804856e: 8d 45 ec lea 0xffffffec(%ebp),%eax 8048571: 8d 50 08 lea 0x8(%eax),%edx 8048574: 8d 45 ec lea 0xffffffec(%ebp),%eax 8048577: 83 c0 04 add $0x4,%eax 804857a: 89 54 24 10 mov %edx,0x10(%esp) 804857e: 89 44 24 0c mov %eax,0xc(%esp) 8048582: 8d 45 ec lea 0xffffffec(%ebp),%eax 8048585: 89 44 24 08 mov %eax,0x8(%esp) 8048589: c7 44 24 04 48 87 04 movl $0x8048748,0x4(%esp) 8048590: 08 8048591: 8b 45 08 mov 0x8(%ebp),%eax 8048594: 89 04 24 mov %eax,(%esp) 8048597: e8 08 fe ff ff call 80483a4 <sscanf@plt> 804859c: 89 45 f8 mov %eax,0xfffffff8(%ebp) 804859f: 83 7d f8 03 cmpl $0x3,0xfffffff8(%ebp) 80485a3: 74 05 je 80485aa <phase_1+0x42> 80485a5: e8 2e 00 00 00 call 80485d8 <explode> 80485aa: c7 45 fc 00 00 00 00 movl $0x0,0xfffffffc(%ebp) 80485b1: 83 6d f8 01 subl $0x1,0xfffffff8(%ebp) 80485b5: eb 0e jmp 80485c5 <phase_1+0x5d> 80485b7: 8b 45 f8 mov 0xfffffff8(%ebp),%eax 80485ba: 8b 44 85 ec mov 0xffffffec(%ebp,%eax,4),%eax 80485be: 01 45 fc add %eax,0xfffffffc(%ebp) 80485c1: 83 6d f8 01 subl $0x1,0xfffffff8(%ebp) 80485c5: 83 7d f8 00 cmpl $0x0,0xfffffff8(%ebp) 80485c9: 79 ec jns 80485b7 <phase_1+0x4f> 80485cb: 83 7d fc 12 cmpl $0x12,0xfffffffc(%ebp) 80485cf: 74 05 je 80485d6 <phase_1+0x6e> 80485d1: e8 02 00 00 00 call 80485d8 <explode> 80485d6: c9 leave 80485d7: c3 ret
08048568 <phase_1>: ; phase_1(char s[]) ;; setup stack frame for phase_1 8048568: 55 push %ebp 8048569: 89 e5 mov %esp,%ebp 804856b: 83 ec 38 sub $0x38,%esp ;; ?? place (not push) parameters on stack before calling sscanf ; -0x24(%ebp) local variable: a 804856e: 8d 45 ec lea 0xffffffec(%ebp),%eax ; make %edx contain address a + 8 8048571: 8d 50 08 lea 0x8(%eax),%edx ; make %eax contain address a 8048574: 8d 45 ec lea 0xffffffec(%ebp),%eax ; now make %eax contain address a + 4 8048577: 83 c0 04 add $0x4,%eax ; move address a + 8 to %esp + 16 804857a: 89 54 24 10 mov %edx,0x10(%esp) ; move address a + 4 to %esp + 12 804857e: 89 44 24 0c mov %eax,0xc(%esp) ; make %eax contain address a 8048582: 8d 45 ec lea 0xffffffec(%ebp),%eax ; address a moved to %esp + 8 8048585: 89 44 24 08 mov %eax,0x8(%esp) ; something moved to %esp + 4 8048589: c7 44 24 04 48 87 04 movl $0x8048748,0x4(%esp) 8048590: 08 ; move 1st param to %eax 8048591: 8b 45 08 mov 0x8(%ebp),%eax ; move 1st param, s, to address %esp + 0 8048594: 89 04 24 mov %eax,(%esp) ;; call sscanf - look at previous instructions for parameters ; sscanf(s, fmt, a, a + 4, a + 8) 8048597: e8 08 fe ff ff call 80483a4 <sscanf@plt> ; -8(%ebp) local variable: n = return value from sscanf 804859c: 89 45 f8 mov %eax,0xfffffff8(%ebp) ;; checking number of conversions by sscanf 804859f: 83 7d f8 03 cmpl $0x3,0xfffffff8(%ebp) ; ; if (n == 3) goto 80485aa 80485a3: 74 05 je 80485aa <phase_1+0x42> 80485a5: e8 2e 00 00 00 call 80485d8 <explode> ; call explode ;; ok 3 numbers read. what next? ; -4(%ebp) local variable: b = 0 80485aa: c7 45 fc 00 00 00 00 movl $0x0,0xfffffffc(%ebp) ; n = n - 1 80485b1: 83 6d f8 01 subl $0x1,0xfffffff8(%ebp) ;; loop starts with unconditional jump to test (at end of loop body) 80485b5: eb 0e jmp 80485c5 <phase_1+0x5d> ; goto 80485c5 80485b7: 8b 45 f8 mov 0xfffffff8(%ebp),%eax ; %eax contains n ; -0x24(%ebp) + 4 * n moved to %eax - that is, %eax = a[n] 80485ba: 8b 44 85 ec mov 0xffffffec(%ebp,%eax,4),%eax 80485be: 01 45 fc add %eax,0xfffffffc(%ebp) ; b = b + a[n] 80485c1: 83 6d f8 01 subl $0x1,0xfffffff8(%ebp) ; n = n - 1 80485c5: 83 7d f8 00 cmpl $0x0,0xfffffff8(%ebp) ; 80485c9: 79 ec jns 80485b7 <phase_1+0x4f> ; if (n >= 0) goto 8045b7 ;jns means jump if the comparison was not negative (not 'signed'; jge) 80485cb: 83 7d fc 12 cmpl $0x12,0xfffffffc(%ebp) ; 80485cf: 74 05 je 80485d6 <phase_1+0x6e> ; if (b == 0x12) goto 80485d6 80485d1: e8 02 00 00 00 call 80485d8 <explode> ; call explode 80485d6: c9 leave 80485d7: c3 ret