0% found this document useful (0 votes)
40 views17 pages

Assembly Code Examples and Exercises

The document contains example assembly problems testing understanding of mapping C code to assembly instructions. Problem 1 has incomplete assembly code for C functions and asks to fill in missing instructions. Problem 2 tests understanding of condition flags set by compare instructions. Problem 3 asks which C function matches given assembly code. Problem 4 provides assembly code fragments and asks which implements a given C switch statement. Problem 5 indicates it tests understanding of how C for loops relate to machine code.

Uploaded by

bzua5253
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
40 views17 pages

Assembly Code Examples and Exercises

The document contains example assembly problems testing understanding of mapping C code to assembly instructions. Problem 1 has incomplete assembly code for C functions and asks to fill in missing instructions. Problem 2 tests understanding of condition flags set by compare instructions. Problem 3 asks which C function matches given assembly code. Problem 4 provides assembly code fragments and asks which implements a given C switch statement. Problem 5 indicates it tests understanding of how C for loops relate to machine code.

Uploaded by

bzua5253
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

Example Assembly Problems

Problem 1:
Consider the following pairs of C functions and assembly code. Fill in the missing instructions in the
assembly code (one instruction per a blank). Your answers should be syntactically correct assembly.

int goose() goose:


{ pushl %ebp
return -4; movl %esp, %ebp
}
___________________________
popl %ebp
ret

int cow(int a, int b) cow:


{ pushl %ebp
return a - b; movl %esp, %ebp
} movl 8(%ebp), %eax

___________________________
popl %ebp
ret

int pig(int a) pig:


{ pushl %ebp
return a*3; movl %esp, %ebp
} movl 8(%ebp), %eax

leal _______________________
popl %ebp
ret

Page 1 of 17
int sheep(int c) sheep:
{ pushl %ebp
if(c < 0) movl %esp, %ebp
return 1; movl 8(%ebp), %eax
else
return 0; ___________________________
} popl %ebp
ret

int duck(int a) duck:


{ pushl %ebp
if(sheep(a)) movl %esp, %ebp
return -a; pushl %ebx
else movl 8(%ebp), %ebx
return a;
} ___________________________
call sheep
movl %ebx, %edx

___________________________
je .L6
negl %edx
.L6:
movl %edx, %eax
addl $4, %esp
popl %ebx
popl %ebp
ret

Page 2 of 17
Problem 2:
This problem tests your understanding of IA32 condition codes.

A. Consider the instruction:


cmpl a,b
Write in the values (0 if clear, 1 if set) of the condition flags if this instruction is executed with the
given values of a and b.

a b Zero Flag (ZF) Sign Flag (SF) Carry Flag (CF) Overflow Flag (OF)

-4 0xfffffffc

4 0xfffffffc

-1 1

2 0x80000000

0x7fffffff 0x80000000

0x80000000 0x7fffffff

1 0x7fffffff

0x80000000 0x80000000

0x7fffffff 0xffffffff

B. On an IA32 architecture, compare and test instructions aren’t the only instructions which set the
condition codes and conditional branches aren’t the only instructions which read the condition codes.
Specifically, the add instruction sets the condition codes based on the result and the add with carry in-
struction (adc) computes the sum of its two operands and the carry flag. That is, adcl %edx,%eax
computes eax = eax + edx + CF. Briefly describe a specific instance where the compiler can
make use of this combination of instructions.

Page 3 of 17
Problem 3:
Consider the following C functions and assembly code:

int fun1(int i, int j)


{
if(i+3 != j)
return i+3;
else
return j*16;
} pushl %ebp
movl %esp, %ebp
int fun2(int i, int j) movl 8(%ebp), %eax
{ movl 12(%ebp), %ecx
if(i+3 != (unsigned)j) leal 3(%eax), %edx
return i; cmpl %ecx, %edx
else jne .L4
return j*4; leal 0(,%ecx,4), %eax
} .L4:
popl %ebp
int fun3(int i, int j) ret
{
if(i+3 <= (unsigned)j)
return i;
else
return j>>2;
}

Which of the functions compiled into the assembly code shown?

Page 4 of 17
Problem 4:
Consider the following C function and assembly code fragments:

int woohoo(int a, int r) Fragment 1


{
int ret = 0; woohoo:
switch(a) pushl %ebp
{ movl %esp, %ebp
case 11: movl 8(%ebp), %edx
ret = 4; movl $0, %ecx
break; cmpl $11, %edx
case 22: jne .L2
case 55: movl $4, %ecx
ret = 7; jmp .L3
break; .L2:
case 33: cmpl $22, %edx
case 44: jne .L3
ret = 11; movl $7, %ecx
break; .L3:
cmpl $55, %edx
default: jne .L5
ret = 1; movl $7, %ecx
} .L5:
return ret; cmpl $33, %edx
} sete %al
cmpl $44, %edx
sete %dl
orl %edx, %eax
testb $1, %al
je .L6
movl $11, %ecx
.L6:
movl %ecx, %eax
popl %ebp
ret

Page 5 of 17
Fragment 2 Fragment 3
woohoo: woohoo:
pushl %ebp pushl %ebp
movl $1, %eax movl %esp,%ebp
movl %esp, %ebp movl 8(%ebp),%eax
movl 8(%ebp), %edx subl $11,%eax
decl %edx je .L6
cmpl $4, %edx subl $11,%eax
ja .L2 je .L7
jmp *.L9(,%edx,4) subl $11,%eax
.section .rodata je .L8
.align 4 subl $11,%eax
.align 4 je .L8
.L9: subl $11,%eax
.long .L3 je .L7
.long .L5 jmp .L9
.long .L7 .L6:
.long .L7 movl $4,%eax
.long .L5 jmp .L4
.text .L7:
.L3: movl $7,%eax
movl $4, %eax jmp .L4
jmp .L2 .L8:
.L5: movl $11,%eax
movl $7, %eax jmp .L4
jmp .L2 .L9:
.L7: movl $1,%eax
movl $11, %eax .L4:
.L2: ret
popl %ebp
ret

Which of the assembly code fragments matches the C function shown?

Page 6 of 17
Problem 5:
This problem tests your understanding of how for loops in C relate to IA32 machine code. Consider the
following IA32 assembly code for a procedure dog():

dog:
pushl %ebp
movl %esp, %ebp
movl 12(%ebp), %ecx
movl $1, %eax
movl 8(%ebp), %edx
cmpl %ecx, %edx
jge .L7
.L5:
imull %edx, %eax
addl $2, %edx
cmpl %ecx, %edx
jl .L5
.L7:
popl %ebp
ret

Based on the assembly code, fill in the blanks below in its corresponding C source code. (Note: you may only use
symbolic variables x, y, i, and result, from the source code in your expressions below — do not use register names.)

int dog(int x, int y)


{
int i, result;

result = ________;

for (i = ________; _____________; ________) {

result = _________________;
}
}
return result;
}

Page 7 of 17
Problem 6:
This problem tests your understanding of how while loops in C relate to IA32 machine code. Consider
the following IA32 assembly code for a procedure cat():

cat:
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %ecx
pushl %ebx
xorl %ebx, %ebx
movl 12(%ebp), %eax
decl %ecx
cmpl $-1, %ecx
je .L6
movl %ecx, %edx
imull %eax, %edx
negl %eax
.p2align 4,,15
.L4:
decl %ecx
addl %edx, %ebx
addl %eax, %edx
cmpl $-1, %ecx
jne .L4
.L6:
movl %ebx, %eax
popl %ebx
popl %ebp
ret

Based on the assembly code, fill in the blanks below in its corresponding C source code. (Note: you may only use
symbolic variables x, y, i, and ret, from the source code in your expressions below — do not use register names.)

int cat(int x, int y) {


int i, ret;

ret = ________;

i = ________;

while(_____________)
{
ret = _______________________;
}
return ret;
}

Page 8 of 17
Problem 7:
This problem tests your understanding of how switch statements in C relate to IA32 machine code. Con-
sider the following IA32 assembly code for a procedure frog():

frog:
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %edx
movl 12(%ebp), %eax
cmpl $7, %edx
ja .L8
jmp *.L9(,%edx,4)
.section .rodata
.align 4
.align 4
.L9:
.long .L8
.long .L4
.long .L8
.long .L5
.long .L8
.long .L4
.long .L6
.long .L2
.text
.L4:
movl $7, %eax
jmp .L2
.L5:
decl %eax
jmp .L2
.L6:
incl %eax
jmp .L2
.L8:
movl $-1, %eax
.L2:
popl %ebp
ret

Page 9 of 17
Based on the assembly code, fill in the blanks below in its corresponding C source code. (Note: you may
only use symbolic variables a, b, and result, from the source code in your expressions below — do not use
register names.)

int frog(int a, int b)


{
int result;

switch(______)
{
case ______:

case ______:

result = ______;
break;

case ______:

result = _________;
break;

case ______:

_________;

case 7:
result = ______;
break;

default:

result = ______;
}

return result;
}

Page 10 of 17
Problem 8:
This problem tests your understanding of the stack discipline and byte ordering. Consider the following C
functions and assembly code:

void top_secret(int len)


{
char buf[8];
scanf("%s", buf);
if(strlen(buf) != len)
exit(1);
}

int main()
{
printf("Enter a passphrase: ");
top_secret(8);
printf("The chicken flies at midnight!\n");
return 0;
}

08048530 <top_secret>:
8048530: 55 push %ebp
8048531: 89 e5 mov %esp,%ebp
8048533: 83 ec 08 sub $0x8,%esp
8048536: 8d 45 f8 lea 0xfffffff8(%ebp),%eax
8048539: 50 push %eax
804853a: 68 40 86 04 08 push $0x8048640
804853f: e8 44 fe ff ff call 8048388 <scanf>
8048544: 8d 45 f8 lea 0xfffffff8(%ebp),%eax
8048547: 50 push %eax
8048548: e8 5b fe ff ff call 80483a8 <strlen>
804854d: 83 c4 0c add $0xc,%esp
8048550: 3b 45 08 cmp 0x8(%ebp),%eax
8048553: 74 0b je 8048560 <top_secret+0x30>
8048555: 6a 01 push $0x1
8048557: e8 8c fe ff ff call 80483e8 <exit>
804855c: 8d 74 26 00 lea 0x0(%esi,1),%esi
8048560: 89 ec mov %ebp,%esp
8048562: 5d pop %ebp
8048563: c3 ret

Page 11 of 17
Here are some notes to help you work the problem:

• scanf("%s", buf) reads an input string from the standard input stream (stdin) and stores it at
address buf (including the terminating \0 character). It does not check the size of the destination
buffer.

• strlen(s) returns the length of the null-terminated string s.

• exit(1) halts execution of the current process without returning.

• Recall that Linux/x86 machines are Little Endian.

You may find the following diagram helpful to work out your answers.

0x0c
0x08
0x04
ebp → 0x00
0xfc
0xf8
0xf4
0xf0
0xec
0xe8
0xe4
0xe0
0xdc
0xd8
0xd4
0xd0

Page 12 of 17
A. Circle the address (relative to ebp) of the following items. Assume that the code has executed up to
(but not including) the call to scanf at 0x804853f).

return address: 0xc 0x08 0x04 0x00 0xfc 0xf8 0xf4 0xf0 0xec 0xe8 0xe4 0xe0

saved %ebp: 0xc 0x08 0x04 0x00 0xfc 0xf8 0xf4 0xf0 0xec 0xe8 0xe4 0xe0

len: 0xc 0x08 0x04 0x00 0xfc 0xf8 0xf4 0xf0 0xec 0xe8 0xe4 0xe0

&buf: 0xc 0x08 0x04 0x00 0xfc 0xf8 0xf4 0xf0 0xec 0xe8 0xe4 0xe0

%esp: 0xc 0x08 0x04 0x00 0xfc 0xf8 0xf4 0xf0 0xec 0xe8 0xe4 0xe0

&“%s”: 0xc 0x08 0x04 0x00 0xfc 0xf8 0xf4 0xf0 0xec 0xe8 0xe4 0xe0

B. Let us enter the string “chickenstonight” (not including the quotes) as a password. Inside the
top secret function scanf will read this string from stdin, writing its value into buf. Afterwards
what will be the value in the 4-byte word pointed to by %ebp? You should answer in hexadecimal
notation.
The following table shows the hexadecimal value for relevant ASCII characters.

Character Hex value Character Hex value


’c’ 0x63 ’h’ 0x68
’i’ 0x69 ’k’ 0x6b
’e’ 0x65 ’n’ 0x6e
’s’ 0x73 ’t’ 0x74
’o’ 0x6f ’g’ 0x67
’h’ 0x68 \0 0x00

(%ebp) = 0x________________________

Page 13 of 17
C. The function top secret is called from a 5-byte call instruction at the address 0x804857f inside
of main. Before the first instruction of top secret (0x08048530) is executed, the registers contain
the following values:

Register Hex Value


eax 0x14
ecx 0x0
edx 0x0
ebx 0x40157770
esp 0xbffff98c
ebp 0xbffff998
esi 0x40015e8c
edi 0xbffffa04
eip 0x8048530

The program continues to execute until it hits the lea instruction at 0x8048544 (right after the call
to tt scanf). The user inputs ’chickens’. Fill in the full 4-byte hexadecimal values for the following
memory locations. If a value is cannot be computed from the information given, write “unknown”.

Address Hex Value

0xbffff990

0xbffff98c

0xbffff988

0xbffff984

0xbffff980

0xbffff97c

0xbffff978

Page 14 of 17
Problem 9:
This problem tests your understanding of the IA32 calling convention. Consider the following C code and
corresponding assembly. Fill in the missing instructions (one instruction per a blank line).

int global; bear:


pushl %ebp
int bear(int i, int j, int k) movl %esp, %ebp
{
for( ; i < j; i++) __________________
{
global += k*i; __________________
} movl 8(%ebp), %edx
return global; movl 12(%ebp), %ebx
} movl 16(%ebp), %esi
cmpl %ebx, %edx
jge .L7
movl global, %ecx
.L5:
movl %esi, %eax
imull %edx, %eax
leal (%ecx,%eax), %ecx
incl %edx
cmpl %ebx, %edx
jl .L5
movl %ecx, global
.L7:

__________________

__________________

__________________
popl %ebp
ret

Page 15 of 17
Problem 10:
The following problem will test your understanding of stack frames. It is based on the following function:

int scrat(int val, int n)


{
int result = 0;
if(n > 0)
result = val + scrat(val, n-1);
return result;
}

A compiler on an IA-32 Linux machine produces the following object code for this function, which we have
disassembled (using objdump) back into assembly code:
08048390 <scrat>:
8048390: 55 push %ebp
->8048391: 89 e5 mov %esp,%ebp
8048393: 53 push %ebx
8048394: 83 ec 08 sub $0x8,%esp
8048397: 8b 5d 08 mov 0x8(%ebp),%ebx
804839a: 8b 45 0c mov 0xc(%ebp),%eax
804839d: ba 00 00 00 00 mov $0x0,%edx
80483a2: 85 c0 test %eax,%eax
80483a4: 7e 10 jle 80483b6 <scrat+0x26>
80483a6: 48 dec %eax
80483a7: 89 44 24 04 mov %eax,0x4(%esp,1)
80483ab: 89 1c 24 mov %ebx,(%esp,1)
80483ae: e8 dd ff ff ff call 8048390 <scrat>
80483b3: 8d 14 18 lea (%eax,%ebx,1),%edx
80483b6: 89 d0 mov %edx,%eax
80483b8: 83 c4 08 add $0x8,%esp
80483bb: 5b pop %ebx
80483bc: 5d pop %ebp
80483bd: c3 ret

A. On the next page, you have the diagram of the stack immediately after some function makes a call
to scrat and the very first instruction of scrat has executed (the next instruction to be executed
is denoted with an arrow (->). The value of register %esp at this point is 0xbffff998. For each
of the numeric values shown in the table, give a short description of the value. If the value has a
corresponding variable in the original C source code, use the name of the variable as its description.

B. Assume that scrat runs until it reaches the position denoted with an arrow (->) again. In the table
on the next stage, fill in the updated stack. Use a numeric value (if possible, else write n/a) and
provide a short description of the value. Cross out any stack space not used.

C. Which instruction (give its address) computes the result of addition?


0x______________________

Page 16 of 17
Address Numeric Value Comments/Description

0xbffff9a4 0x00000003

0xbffff9a0 0x00000021

0xbffff99c 0x080483db

0xbffff998 0xbffff9a8

0xbffff994

0xbffff990

0xbffff98c

0xbffff988

0xbffff984

0xbffff980

0xbffff97c

0xbffff978

0xbffff974

0xbffff970

0xbffff97c

0xbffff978

0xbffff974

Page 17 of 17

You might also like