Difference between revisions of "CSC231 Homework 10 Solution"
(New page: --~~~~ ---- <code><pre> ;;; hw10.asm ;;; John M. Schanck <jms07@hampshire.edu> ;;; Edited (commented) by D. Thiebaut ;;; ;;; Performs a binary search on an array of times and events ...) |
|||
Line 3: | Line 3: | ||
<code><pre> | <code><pre> | ||
+ | |||
+ | |||
+ | * Thiebaut | ||
+ | * My talk | ||
+ | * My preferences | ||
+ | * My watchlist | ||
+ | * My contributions | ||
+ | * Log out | ||
+ | |||
+ | Navigation | ||
+ | |||
+ | * Home | ||
+ | * Research | ||
+ | * Classes | ||
+ | * Tutorials | ||
+ | * Wikis | ||
+ | * Media | ||
+ | * Contact | ||
+ | |||
+ | CSC231 Homework 10 Solution | ||
+ | |||
+ | * Page | ||
+ | * | ||
+ | * Edit | ||
+ | * | ||
+ | * Delete | ||
+ | * Move | ||
+ | * Protect | ||
+ | * Watch | ||
+ | |||
+ | CSC231 Homework 10 Solution | ||
+ | From Dominique Thiebaut -- Computer Science | ||
+ | Jump to: navigation, search | ||
+ | |||
+ | --D. Thiebaut 17:29, 10 December 2008 (UTC) | ||
+ | |||
;;; hw10.asm | ;;; hw10.asm | ||
;;; John M. Schanck <jms07@hampshire.edu> | ;;; John M. Schanck <jms07@hampshire.edu> | ||
Line 64: | Line 100: | ||
db '4' | db '4' | ||
− | arraylen equ ($-dates)/esize ;; arraylen = byte size of array / element size | + | arraylen equ ($-dates)/esize ;; arraylen = byte size of array / element size |
− | key dd | + | key dd 0 ;; The search key |
− | tvsec dd | + | tvsec dd 0, 0 |
− | tvsec2 dd | + | tvsec2 dd 0, 0 |
− | sleeptime dd | + | sleeptime dd 0, 500000000 ;; .5 second |
− | endl db | + | endl db 10 |
Line 78: | Line 114: | ||
.getEvent: | .getEvent: | ||
− | push ecx ;; Store loop counter | + | push ecx ;; Store loop counter |
mov eax, tvsec | mov eax, tvsec | ||
− | push eax | + | push eax ;; push pointer to tvsec onto stack |
− | call getTime ;; and store the current time in it | + | call getTime ;; and store the current time in it |
mov eax, dword[tvsec] | mov eax, dword[tvsec] | ||
and eax, 0x0000000f ;; We're only interested in the time % 16 | and eax, 0x0000000f ;; We're only interested in the time % 16 | ||
mov dword[key], eax ;; Store index in "key" | mov dword[key], eax ;; Store index in "key" | ||
− | + | ;;;--- Perform the search --- | |
xor eax, eax | xor eax, eax | ||
− | push eax ; dword on stack for return value | + | push eax ;; dword on stack for return value |
− | push 0 | + | push 0 ;; Left bound |
mov eax, arraylen - 1 | mov eax, arraylen - 1 | ||
− | push eax ; Right bound | + | push eax ;; Right bound |
mov eax, dword[key] | mov eax, dword[key] | ||
push eax ; Search key | push eax ; Search key | ||
call binary_search | call binary_search | ||
− | pop ebx | + | pop ebx ;; Binary search returns a dword on the stack |
test ebx, ebx | test ebx, ebx | ||
− | js .exit | + | js .exit ;; Exit if returned value is -1 |
− | + | ;;;--- Print the event corresponding to the returned value --- | |
− | imul ebx, esize | + | imul ebx, esize ;; multiply returned index by element size ( 5 bytes ) |
− | add ebx, 4 | + | add ebx, 4 ;; Character we want to print is the 5th byte in the element |
− | add ebx, dates | + | add ebx, dates ;; Add in offset of data array |
push ebx | push ebx | ||
call printChar | call printChar | ||
Line 113: | Line 149: | ||
.wait: | .wait: | ||
− | |||
;; The sleep duration is set to .5 seconds, | ;; The sleep duration is set to .5 seconds, | ||
;; to be absolutely sure we only print each event | ;; to be absolutely sure we only print each event | ||
;; once, make sure the clock has advanced. | ;; once, make sure the clock has advanced. | ||
+ | call sleep | ||
mov eax, tvsec2 | mov eax, tvsec2 | ||
push eax | push eax | ||
− | call getTime | + | call getTime ;; Get current time in tvsec2 |
mov eax, dword[tvsec2] | mov eax, dword[tvsec2] | ||
cmp dword[tvsec], eax ;; keep looping if the time is the same. | cmp dword[tvsec], eax ;; keep looping if the time is the same. | ||
Line 139: | Line 175: | ||
;; | ;; | ||
;;Python example | ;;Python example | ||
− | ;;array = [1,5,6,7,8,10,22] | + | ;; |
− | ;;def binary_search(left, right, key): | + | ;; array = [1,5,6,7,8,10,22] |
− | ;; | + | ;; |
− | ;; | + | ;; def binary_search(left, right, key): |
− | ;; | + | ;; if left > right: |
− | ;; | + | ;; # Exhausted search without finding key |
− | ;; | + | ;; return -1 |
− | ;; | + | ;; mid = (left+right)/2 |
− | ;; | + | ;; if array[mid] == key: |
− | ;; | + | ;; # Found the index |
− | ;; | + | ;; return mid |
− | ;; | + | ;; elif key > array[mid]: |
− | ;; | + | ;; # Search values greater than array[mid] |
− | ;; | + | ;; return binary_search(mid+1, right, key) |
+ | ;; # Search values less than array[mid] | ||
+ | ;; return binary_search(left, mid-1, key) | ||
;;--------------------------------------------------- | ;;--------------------------------------------------- | ||
binary_search: | binary_search: | ||
Line 163: | Line 201: | ||
%define f_key dword[ebp+8] | %define f_key dword[ebp+8] | ||
+ | ;;--- test if pointers overal --- | ||
mov eax, f_left | mov eax, f_left | ||
cmp eax, f_right | cmp eax, f_right | ||
Line 169: | Line 208: | ||
jmp .return | jmp .return | ||
+ | ;;--- is key in the middle? --- | ||
.test: | .test: | ||
mov eax, f_left | mov eax, f_left | ||
Line 184: | Line 224: | ||
jmp .return | jmp .return | ||
+ | ;;--- not found, is key on the left side of middle?--- | ||
.less: | .less: | ||
push eax ;; dword for return value | push eax ;; dword for return value | ||
Line 192: | Line 233: | ||
jmp .recurse ;; binary_search(left, mid-1, key) | jmp .recurse ;; binary_search(left, mid-1, key) | ||
+ | ;;--- not found, is key on the right side of middle? --- | ||
.greater: | .greater: | ||
push eax ;; dword for return value | push eax ;; dword for return value | ||
Line 255: | Line 297: | ||
int 0x80 | int 0x80 | ||
ret | ret | ||
+ | |||
</pre></code> | </pre></code> |
Revision as of 15:02, 10 December 2008
--D. Thiebaut 17:29, 10 December 2008 (UTC)
* Thiebaut
* My talk
* My preferences
* My watchlist
* My contributions
* Log out
Navigation
* Home
* Research
* Classes
* Tutorials
* Wikis
* Media
* Contact
CSC231 Homework 10 Solution
* Page
*
* Edit
*
* Delete
* Move
* Protect
* Watch
CSC231 Homework 10 Solution
From Dominique Thiebaut -- Computer Science
Jump to: navigation, search
--D. Thiebaut 17:29, 10 December 2008 (UTC)
;;; hw10.asm
;;; John M. Schanck <jms07@hampshire.edu>
;;; Edited (commented) by D. Thiebaut
;;;
;;; Performs a binary search on an array of times and events
;;; using the current time as the key, and prints the result.
;;; The execution is limited to 20 seconds, after which the program
;;; stops.
;;;
;;; The array of time events is stored at address "dates" in the data
;;; section.
;;;
;;; to assemble and run:
;;; nasm -f elf -F stabs hw10.asm
;;; ld -o hw10 hw10.o
;;; ./hw10
;;; ===========================================================
%assign SYS_EXIT 1
%assign SYS_WRITE 4
%assign SYS_TIME 78
%assign SYS_SLEEP 162
%assign STDIN 0
%assign STDOUT 1
section .data
dates dd 0
db 'a'
esize equ $-dates ;; Size of each element
dd 1
db 'b'
dd 2
db 'r'
dd 3
db 'a'
dd 4
db 'c'
dd 5
db 'a'
dd 6
db 'd'
dd 7
db 'a'
dd 8
db 'b'
dd 9
db 'r'
dd 10
db 'a'
dd 11
db '!'
dd 12
db '1'
dd 13
db '2'
dd 14
db '3'
dd 15
db '4'
arraylen equ ($-dates)/esize ;; arraylen = byte size of array / element size
key dd 0 ;; The search key
tvsec dd 0, 0
tvsec2 dd 0, 0
sleeptime dd 0, 500000000 ;; .5 second
endl db 10
section .text
global _start
_start:
mov ecx, 20 ;run for 20 seconds
.getEvent:
push ecx ;; Store loop counter
mov eax, tvsec
push eax ;; push pointer to tvsec onto stack
call getTime ;; and store the current time in it
mov eax, dword[tvsec]
and eax, 0x0000000f ;; We're only interested in the time % 16
mov dword[key], eax ;; Store index in "key"
;;;--- Perform the search ---
xor eax, eax
push eax ;; dword on stack for return value
push 0 ;; Left bound
mov eax, arraylen - 1
push eax ;; Right bound
mov eax, dword[key]
push eax ; Search key
call binary_search
pop ebx ;; Binary search returns a dword on the stack
test ebx, ebx
js .exit ;; Exit if returned value is -1
;;;--- Print the event corresponding to the returned value ---
imul ebx, esize ;; multiply returned index by element size ( 5 bytes )
add ebx, 4 ;; Character we want to print is the 5th byte in the element
add ebx, dates ;; Add in offset of data array
push ebx
call printChar
mov ebx, endl
push ebx
call printChar
.wait:
;; The sleep duration is set to .5 seconds,
;; to be absolutely sure we only print each event
;; once, make sure the clock has advanced.
call sleep
mov eax, tvsec2
push eax
call getTime ;; Get current time in tvsec2
mov eax, dword[tvsec2]
cmp dword[tvsec], eax ;; keep looping if the time is the same.
je .wait
pop ecx
loop .getEvent
.exit:
mov eax, SYS_EXIT
int 0x80
;;---------------------------------------------------
;;binary_search: Given a left and right bound, and a
;; key to search for, binary_search will
;; try to find the index of the key within
;; the "dates" array.
;;
;;Python example
;;
;; array = [1,5,6,7,8,10,22]
;;
;; def binary_search(left, right, key):
;; if left > right:
;; # Exhausted search without finding key
;; return -1
;; mid = (left+right)/2
;; if array[mid] == key:
;; # Found the index
;; return mid
;; elif key > array[mid]:
;; # Search values greater than array[mid]
;; return binary_search(mid+1, right, key)
;; # Search values less than array[mid]
;; return binary_search(left, mid-1, key)
;;---------------------------------------------------
binary_search:
push ebp
mov ebp, esp
%define f_ret dword[ebp+20]
%define f_left dword[ebp+16]
%define f_right dword[ebp+12]
%define f_key dword[ebp+8]
;;--- test if pointers overal ---
mov eax, f_left
cmp eax, f_right
jle .test
mov f_ret, -1
jmp .return
;;--- is key in the middle? ---
.test:
mov eax, f_left
add eax, f_right
shr eax, 1 ; eax = middle value = (left + right) / 2
mov ebx, f_key
push eax
imul eax, esize
mov edx, dword[dates + eax]
pop eax
cmp ebx, edx ; Compare middle value to key
jl .less
jg .greater
mov f_ret, eax
jmp .return
;;--- not found, is key on the left side of middle?---
.less:
push eax ;; dword for return value
push f_left
dec eax
push eax
push f_key
jmp .recurse ;; binary_search(left, mid-1, key)
;;--- not found, is key on the right side of middle? ---
.greater:
push eax ;; dword for return value
inc eax
push eax
push f_right
push f_key
jmp .recurse ;; binary_search(mid+1, right, key)
.recurse:
call binary_search
pop eax
mov f_ret, eax
.return:
pop ebp
ret 12
;;--------------------------------------------------
;;getTime: Takes a dword address on the stack and
;; stores the system time at the address
;; referenced.
;;--------------------------------------------------
getTime:
push ebp
mov ebp, esp
%define t_ptr dword[ebp+8]
push eax
mov eax, SYS_TIME
mov ebx, t_ptr
mov ecx, 0
int 0x80
pop eax
pop ebp
ret 4
;;--------------------------------------------------
;;printChar: prints a byte from the address on the stack
;;--------------------------------------------------
printChar:
push ebp
mov ebp, esp
%define char dword[ebp+8]
mov eax, SYS_WRITE
mov ebx, STDOUT
mov ecx, char
mov edx, 1
int 0x80
pop ebp
ret 4
;;--------------------------------------------------
;;sleep: Sleep for length of time defined in sleeptime
;;--------------------------------------------------
sleep:
mov eax, SYS_SLEEP
mov ebx, sleeptime
mov ecx, 0
int 0x80
ret