231a-ag assembly

From CSclasswiki
Jump to: navigation, search

Assembly Program

;;; ; arduino.asm                                                                  
;;; ; Alex Cheng (231a-ag)                                                         
;;; ;                                                                              
;;; ; To assemble, link and run:                                                   
;;; ;  nasm -f elf asm_io.asm                                                      
;;; ;  nasm -f elf arduino.asm                                                     
;;; ;  gcc -o arduino arduino_serial.c asm_io.o arduino.o                          
;;; ; ./arduino                                                                    
;;; ;                                                                              
        %include "asm_io.inc"

%assign EXIT            1
%assign OPEN            5
%assign CLOSE           6
%assign READ            3
%assign CREATE          8
%assign WRITE           4
%assign STDOUT          1
%assign O_CREAT         64
%assign O_RDONLY        0
%assign O_WRONLY        1
%assign O_APPEND        1024
%assign O_RDWR          2
%assign S_IRUSR         00400q
%assign S_IWUSR         00200q
%assign S_IXUSR         00100q

        extern  _getLocalTime   ; function in C driver program                     
        extern  rand            ; C function returning a random int                
        extern  serialport_writebyte
        extern  serialport_write
        extern  serialport_read_until
        extern  displayBuffer
        global  currentTime     ; make this available to C program                 

        extern  buf
        extern  byte
;;;  -------------------------                                                     
;;;  data segment                                                                  
;;;  -------------------------                                                     
                section .data
;;; ; time structure for int 0x80, 78                                              
        currentTime equ $
        tvsec   dd      0       ; number of seconds since midnight                 
        tvusec  dd      0       ; number of useconds                               
;;; ; time structure for local time                                                
        timeinfo equ    $
        tm_sec  dd      0       ; seconds after the minute 0-61*                   
        tm_min  dd      0       ; minutes after the hour          0-59             
        tm_hour dd      0       ; hours since midnight    0-23                     
        tm_mday dd      0       ; day of the month        1-31                     
        tm_mon  dd      0       ; months since January    0-11                     
        tm_year dd      0       ; years since 1900                                 
        tm_wday dd      0       ; days since Sunday       0-6                      
        tm_yday dd      0       ; days since January 1    0-365                    
        tm_dst  dd      0       ; Daylight Saving Time flag                        
        TIMELEN equ     ($-timeinfo)/4

        errorMsg db     "Error accessing file!", 0x0a, 0
        errorMsg1 db    "Error opening file!", 0x0a, 0
        usb     db      "/dev/ttyUSB0", 0
        handle  dd      0
        noRead  dd      0
        on      db      "w d 13 1", 0x0d
        onLen   equ     $-on
        off     db      "w d 13 0", 0x0d
        offLen  equ     $-off
        read    db      "r d", 0
        readLen equ     $-read

        hour    dd      16
        min     dd      11
        sec     dd      0

        first   db      1
        second  db      2

        firstE  db      0
        secondE db      0

                section .bss
        %assign MAXBUF  100
        buffer  resb    MAXBUF

;;;  -------------------------                                                     
;;;  code area                                                                     
;;;  -------------------------                                                     
                section .text
                global  asm_main
asm_main:

;;; ; get the local time in year, month, day, hour, min, sec...                    

        call    getLocalTime

        mov     ecx, 10
for:
        push    ecx
        call    rand    ;rand returns # in eax                                     
        and     eax, 0x000003ff ;keep only last 10 bits                            
        call    print_int
        call    print_nl
        pop     ecx
        loop    for

;;;  return to C program                                                           
        ret

;;; ; ------------------------------------------------------------------           
;;; ; getTimeOfDay: asks Linux for the # of seconds since Jan 1, 1970.             
;;; ; ------------------------------------------------------------------           
getTimeOfDay:
        mov     eax, 78 ; system call: get time of day                             
        mov     ebx, tvsec ; address of buffer for secs/usecs                      
        mov     ecx, 0     ; NULL for timezone                                     
        int     0x80
        ret

;;; ; ------------------------------------------------------------------           
;;; ; getLocalTime: first gets the time of day, then ask Linux to transform        
;;; ;               this information into month, day, hours, minutes, sec.,        
;;; ;               etc.  The information is stored in the dwords stored at        
;;; ;               timeinfo in the data segment.                                  
;;; ; ------------------------------------------------------------------           
getLocalTime:
;;; ; get the # of sec since Jan 1, 1970                                           
        call    getTimeOfDay

;;; ; transform this # of sec into local time                                      
        call    _getLocalTime ; call the C function                                

        mov     esi, eax
        mov     edi, timeinfo
        mov     ecx, TIMELEN

copyTime:
        mov     eax, [esi]
        mov     [edi],eax
        add     esi, 4
        add     edi, 4
        loop    copyTime

        ret

cmpHour:
        call    getTimeOfDay            ; get time                                 
        mov     eax, [tm_hour]          ; move hour into eax                       
        cmp     eax, dword[hour]        ; compare hour with alarm hour             
        je      cmpMin                  ; if equal, compare minutes                
        call    cmpHour                 ; otherwise, call function again           

cmpMin:
        mov     eax, [tm_min]           ; move minute into eax                     
        cmp     eax, dword[min]         ; compare minute with alarm minute         
        je      cmpSec                  ; if equal, compare seconds                
        call    cmpHour                 ; otherwise, compare hour again            

cmpSec:
        mov     eax, [tm_sec]           ; move seconds into eax                    
        cmp     eax, dword[sec]         ; compare seconds with alarm seconds       
        je      buzzerOn                ; if equal, turn buzzer on                 
        call    cmpHour                 ; otherwise, compare hour again            

buzzerOn:                               ; turn buzzer on                           
        mov     ebx, usb
        call    openFile
        mov     dword[handle], eax
        mov     ebx, [handle]
        mov     ecx, on
        mov     edx, onLen
        call    writeFile
        mov     ebx, dword[handle]
        call    closeFile

readPins:                               ; read Arduino pins                        
        mov     eax, read
        mov     ecx, readLen
        call    copyMsg
        call    serialport_write

        call    serialport_read_until
        call    displayBuffer

keypadInput:
        mov     al, byte[firstE]
        cmp     al, "0"                 ; compare first entered to 0               
        je      firstKeypad             ; if equal, last pressed key               
                                        ; belongs in first entered                 
        mov     al, byte[secondE]
        cmp     al, "0"                 ; compare second entered to 0              
        je      secondKeypad            ; if equal, last pressed key               
                                        ; belongs in second entered                
        ret

firstKeypad:
        mov     al, [buffer]
        cmp     al, byte[first]         ; compare first key pressed to correct key
        jne     wrong                   ; not equal, wrong key                     
        mov     [firstE], al            ; equal, move to first entered             
        call    readPins                ; read pins again                          

secondKeypad:
        mov     al, [buffer]
        cmp     al, byte[firstE]        ; compare last key pressed to              
                                        ; first entered                            
        je      readPins                ; equal, read pins again                   
        cmp     al, byte[second]        ; not equal, compare second key pressed    
                                        ; to correct key                           
        jne     wrong                   ; not equal, wrong key                     
        mov     [secondE], al           ; equal, move to second entered            
        call    readPins                ; read pins again                          

wrong:
;;; ; we're done!                                                                  
        ret

;;; ; if there's a problem, we exit right away                                     
exit:
        mov     eax,EXIT
        mov     ebx,0
        int     0x80    ; final system call                                        

;;; ; --------------------------------------------------------                     
;;; ; openFile                                                                     
;;; ; put address of ASCIIZ file name in ebx                                       
;;; ; handle returned in eax                                                       
;;; ; --------------------------------------------------------                     
openFile:
                mov     eax, OPEN
                mov     ecx,O_WRONLY | O_APPEND ; mode for opening file            
                mov     edx,S_IRUSR | S_IWUSR
                int     0x80
                test    eax,eax ; test for errors                                  
                jns     doneOpenFile
                mov     eax, errorMsg1
                call    print_string
                jmp     exit
doneOpenFile:
                ret             ; handle in eax                                    

;;; ; --------------------------------------------------------                     
;;; ; closeFile: the handle must be in ebx on entry.                               
;;; ;               Closes the file                                                
;;; ; --------------------------------------------------------                     
closeFile:
                mov     eax,CLOSE
                int     0x80
                ret

;;; ; --------------------------------------------------------                     
;;; ; readFile: on entry:                                                          
;;; ;                  handle in ebx                                               
;;; ;                  buffer address in ecx                                       
;;; ;                  max buffer length in edx                                    
;;; ; on exit: number of chars read in eax                                         
;;; ; --------------------------------------------------------                     
readFile:
                mov     eax,READ
                int     0x80
                test    eax,eax
                jns     doneReadFile
                mov     eax, errorMsg
                call    print_string
                jmp     exit
doneReadFile:
                ret

;;; ; --------------------------------------------------------                     
;;; ; writeFile:                                                                   
;;; ; on entry:                                                                    
;;; ;         handle is in ebx                                                     
;;; ;         buffer address is in ecx,                                            
;;; ;         number of chars is in edx.                                           
;;; ; --------------------------------------------------------                     
writeFile:
                mov     eax,WRITE
                int     0x80
                test    eax,eax
                jns     doneWriteFile
                mov     eax, errorMsg
                call    print_string
                jmp     exit
doneWriteFile:
                ret

;;; ; --------------------------------------------------------                     
;;; ; copyMsg: puts array whose address in eax in external                         
;;; ;          buffer number of bytes should be in ecx.                            
;;; ; --------------------------------------------------------                     
copyMsg:
        pushad
        mov     esi, eax        ; source buffer                                    
        mov     edi, buf        ; destination buffer in C program                  
.for
        mov     al, [esi]
        mov     [edi], al
        inc     esi
        inc     edi
        loop    .for
        popad

        ret