Difference between revisions of "CSC231 Exercises On Functions"
(→Exercise 1) |
(→Exercise 4) |
||
(29 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
[[CSC231_Class_Page | Back]] to Weekly Schedule. | [[CSC231_Class_Page | Back]] to Weekly Schedule. | ||
---- | ---- | ||
+ | Note: For some exercises, highlight the white section on the right hand-side of each code section to see the solution. | ||
+ | [[Image:pushPop.jpg| right]] | ||
=Exercise 1= | =Exercise 1= | ||
− | What is the behavior of this loop? | + | * Write a program that prints all the letters of the alphabet in a loop. All the characters appear on the same line. Do not use a function yet! Use '''ecx''' and '''loop''' to control the looping. Make your program print 1 letter per loop. |
+ | * use int 0x80 to print the character (which you'll store in a string). | ||
+ | |||
+ | =Exercise 2= | ||
+ | |||
+ | * Same exercise, but this time use a function that receives the character to be printed in al. | ||
+ | * Explore ways to save ecx in a temporary variable | ||
+ | * Explore alternative ways using the '''push''' and '''pop''' operations | ||
+ | |||
+ | =Exercise 3= | ||
+ | |||
+ | * Print all the characters on separate lines. You cannot use a library function for printing the 0x0a line-feed character. | ||
+ | * Explore a solution where the new-line character is printed at the same time the letter of the alphabet is printed. | ||
+ | * Explore a solution where you have a separate ''myPrintLn'' function that prints a new-line character. | ||
+ | |||
+ | =Exercise 4= | ||
+ | |||
+ | * What is the behavior of the stack, and the resulting values in the registers as this program is executing: | ||
+ | <br /> | ||
+ | <source lang="asm"> | ||
+ | mov eax, 0x01234567 | ||
+ | mov ebx, 0x89ABCDEF | ||
+ | xor ecx, ecx | ||
+ | |||
+ | push ax | ||
+ | pop cx | ||
+ | |||
+ | push ax | ||
+ | push bx | ||
+ | pop ecx | ||
+ | |||
+ | call next | ||
+ | next: pop ecx | ||
+ | |||
+ | </source> | ||
+ | <br /> | ||
+ | |||
+ | [[Media:file.pdf|.]] | ||
+ | |||
+ | =Exercise 5= | ||
+ | |||
+ | What is the behavior of this program? | ||
+ | {| | ||
+ | ! width="300" | | ||
+ | ! width="300" | | ||
+ | |- | ||
+ | | | ||
+ | <source lang="asm"> | ||
+ | mov eax, 0 | ||
+ | mov ecx, 10 | ||
+ | for: call func1 | ||
+ | |||
+ | |||
+ | func1: add eax, 1 | ||
+ | ret | ||
+ | |||
+ | ;;; exit code | ||
+ | mov ebx, 0 | ||
+ | mov eax, 1 | ||
+ | int 0x80 | ||
+ | </source> | ||
+ | | | ||
+ | <font color="white"> | ||
+ | <br> | ||
+ | The loop goes 10 times and the function is called 10 times, adding 1 to eax every time. Eax ends with 10 in it. | ||
+ | </font> | ||
+ | |} | ||
+ | |||
+ | =Exercise 6= | ||
+ | What is the behavior of this program? Draw the stack as the processor executes this program: | ||
{| | {| | ||
+ | ! width="300" | | ||
+ | ! width="300" | | ||
|- | |- | ||
− | |||
| | | | ||
− | < | + | <source lang="asm"> |
mov eax, 0 | mov eax, 0 | ||
+ | mov ebx, 0 | ||
mov ecx, 10 | mov ecx, 10 | ||
for: call func1 | for: call func1 | ||
... | ... | ||
loop for | loop for | ||
+ | |||
func1: add eax, 1 | func1: add eax, 1 | ||
+ | call func2 | ||
+ | ret | ||
+ | |||
+ | func2: add ebx, 1 | ||
ret | ret | ||
− | </ | + | </source> |
| | | | ||
<font color="white"> | <font color="white"> | ||
− | The | + | <br> |
− | </font> | + | Just go through the motion and draw the stack. The return address of the instruction after the call gets pushed in the stack every time the processor executes a '''call'''. It is popped out of the stack every time the processor executes a '''ret'''.</font> |
|} | |} | ||
− | =Exercise | + | =Exercise 7= |
− | Same question | + | Same question, but now observe that the programmer forgot the '''ret''' instruction at the end of the first function. |
− | < | + | {| |
+ | ! width="300" | | ||
+ | ! width="300" | | ||
+ | |- | ||
+ | | | ||
+ | <source lang="asm"> | ||
mov eax, 0 | mov eax, 0 | ||
+ | mov ebx, 0 | ||
mov ecx, 10 | mov ecx, 10 | ||
for: call func1 | for: call func1 | ||
Line 36: | Line 120: | ||
− | func1: | + | |
+ | func1: add eax, 1 | ||
+ | call func2 | ||
+ | |||
+ | func2: add ebx, 1 | ||
ret | ret | ||
− | </ | + | </source> |
+ | | | ||
+ | <font color="white"> | ||
+ | <br> | ||
+ | Just go through the motion and draw the stack. Now the problem is that when the main program calls func1 the first time, the return address for the ellipses is pushed in the stack, then the processor starts executing the '''add eax,1''' function. Then it executes the '''call func2''' instruction and pushes the address of the '''add ebx,1''' instruction in the stack. Then, when it executes the '''ret''' instruction, the address of '''add ebx,1''' is popped out, and ebx is incremented by 1. Then the '''ret''' is executed and we return to the main function. The end result is that func1 is executed once, and func2 twice!</font> | ||
+ | |} | ||
− | =Exercise | + | =Exercise 8 (Push and Pop)= |
− | + | What are the numbers stored in eax and ebx when the loop terminates? If we assume that the default stack is 2 KB long, what is the largest number of times the loop can iterate before the stack overflows (trick question :-)? | |
− | < | + | {| |
+ | ! width="300" | | ||
+ | ! width="300" | | ||
+ | |- | ||
+ | | | ||
+ | <source lang="asm"> | ||
mov eax, 0 | mov eax, 0 | ||
mov ebx, 0 | mov ebx, 0 | ||
mov ecx, 10 | mov ecx, 10 | ||
− | for: call func1 | + | for: push ebx |
+ | call func1 | ||
+ | pop ebx | ||
+ | loop for | ||
... | ... | ||
− | |||
− | |||
− | |||
func1: add eax, 1 | func1: add eax, 1 | ||
Line 58: | Line 156: | ||
func2: add ebx, 1 | func2: add ebx, 1 | ||
ret | ret | ||
− | </ | + | </source> |
+ | | | ||
+ | <font color="white"> | ||
+ | <br> | ||
+ | The loop does '''not''' modify ebx! | ||
+ | </font> | ||
+ | |} | ||
− | =Exercise | + | =Exercise 9= |
− | Same question, but now observe that | + | Same question, but now observe that we pop eax, not ebx... |
− | < | + | {| |
+ | ! width="300" | | ||
+ | ! width="300" | | ||
+ | |- | ||
+ | | | ||
+ | <source lang="asm"> | ||
mov eax, 0 | mov eax, 0 | ||
mov ebx, 0 | mov ebx, 0 | ||
mov ecx, 10 | mov ecx, 10 | ||
− | for: call func1 | + | for: push ebx |
+ | call func1 | ||
+ | pop eax | ||
+ | loop for | ||
... | ... | ||
− | |||
− | |||
− | |||
func1: add eax, 1 | func1: add eax, 1 | ||
call func2 | call func2 | ||
+ | ret | ||
func2: add ebx, 1 | func2: add ebx, 1 | ||
ret | ret | ||
− | </ | + | </source> |
+ | | | ||
+ | <font color="white"> | ||
+ | <br> | ||
+ | This one requires the use of the debugger for fully understanding it! :-) | ||
+ | </font> | ||
+ | |} | ||
+ | |||
+ | =Exercise 10= | ||
+ | |||
+ | What do these 2 code sections do? | ||
+ | |||
+ | {| | ||
+ | ! width="300" | | ||
+ | ! width="300" | | ||
+ | |- | ||
+ | | | ||
+ | <source lang="asm"> | ||
+ | push eax | ||
+ | mov eax, ebx | ||
+ | pop ebx | ||
+ | </source> | ||
+ | |||
+ | and | ||
+ | |||
+ | <source lang="asm"> | ||
+ | xor eax, ebx | ||
+ | xor ebx, eax | ||
+ | xor eax, ebx | ||
+ | </source> | ||
+ | |||
+ | | | ||
+ | <font color="white"> | ||
+ | <br /> | ||
+ | They both swap the contents of '''eax''' and '''ebx'''. | ||
+ | </font> | ||
+ | |} |
Latest revision as of 09:55, 21 October 2014
Back to Weekly Schedule.
Note: For some exercises, highlight the white section on the right hand-side of each code section to see the solution.
Contents
Exercise 1
- Write a program that prints all the letters of the alphabet in a loop. All the characters appear on the same line. Do not use a function yet! Use ecx and loop to control the looping. Make your program print 1 letter per loop.
- use int 0x80 to print the character (which you'll store in a string).
Exercise 2
- Same exercise, but this time use a function that receives the character to be printed in al.
- Explore ways to save ecx in a temporary variable
- Explore alternative ways using the push and pop operations
Exercise 3
- Print all the characters on separate lines. You cannot use a library function for printing the 0x0a line-feed character.
- Explore a solution where the new-line character is printed at the same time the letter of the alphabet is printed.
- Explore a solution where you have a separate myPrintLn function that prints a new-line character.
Exercise 4
- What is the behavior of the stack, and the resulting values in the registers as this program is executing:
mov eax, 0x01234567
mov ebx, 0x89ABCDEF
xor ecx, ecx
push ax
pop cx
push ax
push bx
pop ecx
call next
next: pop ecx
Exercise 5
What is the behavior of this program?
mov eax, 0
mov ecx, 10
for: call func1
func1: add eax, 1
ret
;;; exit code
mov ebx, 0
mov eax, 1
int 0x80
|
|
Exercise 6
What is the behavior of this program? Draw the stack as the processor executes this program:
mov eax, 0
mov ebx, 0
mov ecx, 10
for: call func1
...
loop for
func1: add eax, 1
call func2
ret
func2: add ebx, 1
ret
|
|
Exercise 7
Same question, but now observe that the programmer forgot the ret instruction at the end of the first function.
mov eax, 0
mov ebx, 0
mov ecx, 10
for: call func1
...
loop for
func1: add eax, 1
call func2
func2: add ebx, 1
ret
|
|
Exercise 8 (Push and Pop)
What are the numbers stored in eax and ebx when the loop terminates? If we assume that the default stack is 2 KB long, what is the largest number of times the loop can iterate before the stack overflows (trick question :-)?
mov eax, 0
mov ebx, 0
mov ecx, 10
for: push ebx
call func1
pop ebx
loop for
...
func1: add eax, 1
call func2
ret
func2: add ebx, 1
ret
|
|
Exercise 9
Same question, but now observe that we pop eax, not ebx...
mov eax, 0
mov ebx, 0
mov ecx, 10
for: push ebx
call func1
pop eax
loop for
...
func1: add eax, 1
call func2
ret
func2: add ebx, 1
ret
|
|
Exercise 10
What do these 2 code sections do?
push eax
mov eax, ebx
pop ebx
and xor eax, ebx
xor ebx, eax
xor eax, ebx
|
|