ics312_countodds.asm [Download]
; This simple program takes 10 integers from the user and
; counts how many of these integers are odd
%include "asm_io.inc"
segment .data
msg_odd db "The number of odd numbers is: ",0
segment .bss
integers resd 10 ; space to store 10 32-bit integers
segment .text
global asm_main
asm_main:
enter 0,0 ; set up
pusha ; set up
push integers ; we pass integers to get_integers
push dword 10 ; we pass the number of integers to get_integers
call get_integers ; call get_integers
add esp, 8 ; clean up the stack (often done as op ecx twice, which may be quicker)
mov eax, msg_odd ; store the address of the message to print into eax
call print_string ; print the message
push integers ; we pass integers to count_odds
push 10 ; we pass the number of integers to count_odds
call count_odds ; call count_odds
add esp, 8 ; clean up the stack
call print_int ; print the content of eax as an integer (this is what count_odds returned)
call print_nl ; print a new line
popa ; clean up
mov eax, 0 ; clean up
leave ; clean up
ret ; clean up
; FUNCTION: Get_Integers
; Takes two parameters: an address in memory in which to store integers, and a number of integers to store (>0)
; Destroys values of eax, ebx, and ecx!!
segment .data
msg_int db "Enter an integer: ",0
segment .text
get_integers:
push ebp ; save the value of EBP of the caller
mov ebp, esp ; update the value of EBP for this subprogram
mov ecx, [ebp + 12] ; ECX = address at which to store the integers (parameter #1)
mov ebx, [ebp + 8] ; EBX = number of integers to read (parameter #2)
shl ebx, 2 ; EBX = EBX * 4 (unsigned)
add ebx, ecx ; EBX = ECX + EBX = address beyond that of the last integer to be stored
loop1:
mov eax, msg_int ; EAX = address of the message to print
call print_string; ; print the message
call read_int ; read an integer from the keyboard (which will be stored in EAX)
mov [ecx], eax ; store the integer in memory at the correct address
add ecx, 4 ; ECX = ECX + 4
cmp ecx, ebx ; compare ECX, EBX
jb loop1 ; if ECX < EBX, jump to loop1 (unsigned)
pop ebp ; restore the value of EBP
ret ; clean up
; FUNCTION: count_odds
; Takes two parameters: an address in memory in which integers are stored, and the number of integers (>0)
; Destroys values of eax, ebx, and edx!! (eax = returned value)
segment .text
count_odds:
push ebp ; save the value of EBP of the caller
mov ebp, esp ; update the value of EBP for this subprogram
mov eax, [ebp + 12] ; ECX = address at which integers are stored (parameter #1)
mov ebx, [ebp + 8] ; EBX = number of integers (parameter #2)
shl ebx, 2 ; EBX = EBX * 4 (unsigned)
add ebx, eax ; EBX = ECX + EBX = address beyond that of the last integer
sub ebx, 4 ; EBX = EBX - 4 = address of the last integer
xor edx, edx ; EDX = 0
loop2:
push dword [ebx] ; store the current integer on the stack
call is_odd ; call is_odd
add esp, 4 ; clean up the stack
add edx, eax ; EDX += EAX (EAX = 0 if even, EAX = 1 if odd)
sub ebx, 4 ; ECX = ECX - 4
cmp ebx, [ebp+12] ; compare EBX and the address of the first integer
jnb loop2 ; if EBX >= [EBP+12] jump to loop2 (unsigned)
mov eax, edx ; EAX = EDX (= number of odd integers)
pop ebp ; restore the value of EBP
ret ; clean up
; FUNCTION: is_odd
; Takes one parameter: an integers (>0)
; Destroys values of eax and ecx (eax = returned value)
segment .text
is_odd:
push ebp ; save the value of EBP of the caller
mov ebp, esp ; update the value of EBP for this subprogram
mov eax, 0 ; EAX = 0
mov ecx, [ebp+8] ; EBX = integer (parameter #1)
shr ecx, 1 ; Right logical shift
adc eax, 0 ; EAX = EAX + carry (if even: EAX = 0, if odd: EAX = 1)
pop ebp ; restore the value of EBP
ret ; clean up
ics312_fibonacci.asm [Download]
; This simple program takes 10 integers from the user and
; counts how many of these integers are odd
%include "asm_io.inc"
segment .data
msg1 db "Enter n: ", 0
msg2 db "The result is: ", 0
segment .text
global asm_main
asm_main:
enter 0,0 ; set up
pusha ; set up
mov eax, msg1 ; eax = address of msg1
call print_string ; print msg1
call read_int ; get an integer from the keyboard (in EAX)
push eax ; put the integer on the stack (parameter #1)
call f ; call recursive_sum
pop ebx ; remove the parameter from the stack
mov ebx, eax ; save the value returned by recursive_sum
mov eax, msg2 ; eax = address of msg2
call print_string ; print msg2
mov eax, ebx ; eax = sum
call print_int ; print the sum
call print_nl ; print a new line
popa ; clean up
mov eax, 0 ; clean up
leave ; clean up
ret ; clean up
; FUNCTION: f
; Takes one parameter: an integer
; eax = return value
segment .data
debug1 db "Function f called with integer: ",0
segment .text
f: enter 8,0 ; num in [ebp+8], local var x in [ebp-4], local var sum in [ebp-8]
push ebx ; save ebx
push ecx ; save ecx
push edx ; save edx
mov eax, [ebp+8] ; eax = num
sub eax, 2 ; eax -= 2
jns next ; if not <0, goto next
add eax, 2 ; eax += 2
jmp end
next:
mov eax, [ebp+8] ; eax = num
add eax, -1 ; eax -= 1
push eax ; put (num -1) on the stack
call f ; call f (recursively)
add esp, 4 ; remove (num-1) from the stack
mov [ebp-4], eax ; put the returned value in x
mov eax, [ebp+8] ; eax = num
add eax, -2 ; eax -= 2
push eax ; put (num -2) on the stack
call f ; call f (recursively), the return value is in eax
add esp, 4 ; remove (num-1) from the stack
add eax, [ebp-4] ; eax += x
end:
pop edx ; restore ebx
pop ecx ; restore ecx
pop ebx ; restore edx
leave ; clean up the stack
ret ; return
ics312_recursivesum.asm [Download]
; This simple program takes 10 integers from the user and
; counts how many of these integers are odd
%include "asm_io.inc"
segment .data
msg1 db "Enter n: ", 0
msg2 db "The sum is: ", 0
segment .text
global asm_main
asm_main:
enter 0,0 ; set up
pusha ; set up
mov eax, msg1 ; eax = address of msg1
call print_string ; print msg1
call read_int ; get an integer from the keyboard (in EAX)
push eax ; put the integer on the stack (parameter #1)
call recursive_sum ; call recursive_sum
pop ebx ; remove the parameter from the stack
mov ebx, eax ; save the value returned by recursive_sum
mov eax, msg2 ; eax = address of msg2
call print_string ; print msg2
mov eax, ebx ; eax = sum
call print_int ; print the sum
call print_nl ; print a new line
popa ; clean up
mov eax, 0 ; clean up
leave ; clean up
ret ; clean up
; FUNCTION: recursive_sum
; Takes one parameter: an integer
; Destroys values of eax, ebx, ecx, and edx!! (eax = return value)
segment .bss
value resd 1 ; to store the return value temporarily
segment .text
recursive_sum:
push ebp ; save ebp
mov ebp, esp ; set EBP = ESP
pusha ; save all registers (probably overkill)
mov ebx, [ebp+8] ; ebx = integer (parameter #1)
cmp ebx, 0 ; ebx = 0 ?
jnz next ; if (ebx != 0) go to next
xor ecx, ecx ; ECX = 0
jmp end ; Jump to end
next:
mov ecx, ebx ; ECX = EBX
dec ecx ; ECX = ECX - 1
push ecx ; put ECX on the stack
call recursive_sum ; recursive call to recursive_sum!
pop edx ; pop the parameter from the stack
add ebx, eax ; EBX = EBX + recursive_sum(EBX -1)
mov ecx, ebx ; ECX = EBX
end: ; at this point, ECX contains the result
mov [value], ecx ; save ECX, the return value, in memory
popa ; restore all registers
mov eax, [value] ; put the saved returned value into eax
pop ebp ; restore EBP
ret ; return