Difference between revisions of "CSC231 Homework 10 Solution"

From dftwiki3
Jump to: navigation, search
(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 0  ;; The search key
+
key        dd 0  ;; The search key
tvsec      dd 0, 0
+
tvsec      dd 0, 0
tvsec2      dd 0, 0
+
tvsec2      dd 0, 0
sleeptime  dd 0, 500000000  ;; .5 second
+
sleeptime  dd 0, 500000000  ;; .5 second
endl        db 10
+
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 pointer to tvsec onto stack
+
     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
+
;;;--- 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   ; Left bound
+
     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         ; Binary search returns a dword on the stack  
+
     pop    ebx         ;; Binary search returns a dword on the stack  
 
     test    ebx, ebx
 
     test    ebx, ebx
     js      .exit       ; Exit if returned value is -1
+
     js      .exit       ;; Exit if returned value is -1
 
      
 
      
    ;; Print the event corresponding to the returned value
+
;;;--- Print the event corresponding to the returned value ---
     imul    ebx, esize ; multiply returned index by element size ( 5 bytes )
+
     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, 4     ;; Character we want to print is the 5th byte in the element
     add    ebx, dates ; Add in offset of data array
+
     add    ebx, dates ;; Add in offset of data array
 
     push    ebx
 
     push    ebx
 
     call    printChar
 
     call    printChar
Line 113: Line 149:
 
.wait:
 
.wait:
  
    call    sleep
 
 
     ;; 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     ;; Get current time in tvsec2
+
     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]
;; if left > right:
+
;;
;;     # Exhausted search without finding key
+
;; def binary_search(left, right, key):
;;     return -1
+
;;   if left > right:
;; mid = (left+right)/2  
+
;;       # Exhausted search without finding key
;; if array[mid] == key:
+
;;       return -1
;;     # Found the index
+
;;   mid = (left+right)/2  
;;     return mid
+
;;   if array[mid] == key:
;; elif key > array[mid]:
+
;;       # Found the index
;;     # Search values greater than array[mid]
+
;;       return mid
;;     return binary_search(mid+1, right, key)
+
;;   elif key > array[mid]:
;; # Search values less than array[mid]
+
;;       # Search values greater than array[mid]
;; return binary_search(left, mid-1, key)
+
;;       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