Leap Year

Assignment 1

Leap​ ​Year

Task: ​​ ​Design​ ​and​ ​write​ ​an​ ​assembly​ ​code​ ​that​ ​will​ ​determine​ ​if​ ​a​ ​given​ ​year​ ​is​ ​a​ ​Leap​ ​Year.

Things​ ​to​ ​consider
● How​ ​to​ ​change​ ​a​ ​string​ ​of​ ​numbers​ ​into​ ​its​ ​numerical​ ​counterpart
o Helpful​ ​Hit:
▪ Take​ ​a​ ​4-digit​ ​string
▪ Get​ ​the​ ​thousands​ ​digit
▪ Multiply​ ​by​ ​10
▪ Add​ ​the​ ​hundred’s​ ​digit
▪ Multiply​ ​by​ ​10
▪ etc.….
● What​ ​defines​ ​a​ ​leap​ ​year
A​ ​year​ ​is​ ​a​ ​leap​ ​year​ ​if​ ​it​ ​is​ ​divisible​ ​by​ ​4​ ​and​ ​not​ ​divisible​ ​by​ ​100,​ ​unless​ ​it​ ​is​ ​also
divisible​ ​by​ ​400.
● Would​ ​any​ ​loops​ ​(jmp​ ​to​ ​self),​ ​or​ ​if​ ​else​ ​statements​ ​(je​ ​or​ ​jne)​ ​that​ ​would​ ​be​ ​useful
Loop:
~~~~
Code
~~~~
jmp​ ​Loop
Compares:
cmp​ ​~x~,​ ​~y~
je​ ​~~something~~
jne​ ​~~something​ ​else~~

Solution 

lab4.asm

;  lab4.asm Design? ?and? ?write? ?an? ?assembly? ?code? ?that? ?will? ?determine? ?if? ?a? ?given? ?year? ?is? ?a? ?Leap? ?Year

;

; compile:  nasm -f elf64 -l lab4.lst  lab4.asm

;                 ld -o lab4 lab4.o

; run:              ./lab4

SECTION .data           ; data section

question:

db “Type year:”,10      ; the string to print, 10=cr

len: equ $-question           ; “$” means “here”

; len is a value, not an address

fourhundred:

dq 400

hundred:

dq 100

four:

dq 4

message:    db “This year is a leapyear”, 10, 0 ; the string to print, 10=cr

message.length:   equ     $-message

message1:    db “This year is not a leapyear”, 10, 0 ; the string to print, 10=cr

message1.length: equ          $-message1

error:  db “Error”, 10, 0 ; the string to print, 10=cr

error.length: equ       $-error

SECTION .bss

inp_bufresb 256

SECTION .text           ; code section

global _start

section .text

_start:

mov   edx,len           ; arg3, length of string to print

mov   ecx,question      ; arg2, pointer to string

mov   ebx,1       ; arg1, where to write, screen

mov   eax,4       ; write sysout command to int 80 hex

int   0x80        ; interrupt 80 hex, call kernel

mov  eax,3        ;sys_read. Read what user inputs

mov  ebx,0        ;From stdin

movecx,inp_buf    ;Save user input to buffer.

int    80h

xorrax, rax                   ; clear rax

learsi,[inp_buf]

leardi,[inp_buf]

mov rcx,4

callstring_to_int

; RAX now contains year number

pushrax                ; save year

xorrdx, rdx            ; clear

div qword [fourhundred] ; mod year by 400

cmprdx, 0

jzprintLeapYear        ; if divisible by 400 it is a leap year

poprax                 ; load year

pushrax                ; save year

xorrdx, rdx

div qword [hundred]     ; divide year by 100

cmprdx, 0

jzprintNoLeapYear           ; if divisible 100 it is not a leap year

poprax                 ; load year

pushrax                ; save year

xorrdx, rdx

div qword [four]        ; divide year by 4

cmprdx, 0

jzprintLeapYear        ; if divisible by 4 it is a leap year

jnzprintNoLeapYear          ; else it is not a leap year

jmp exit

printLeapYear:

poprax

movrsi, message

movrdx, message.length

xorrax, rax

movrax, 1                  ; system call 1 is write

movrdi, 1                  ; file handle 1 is stdout

syscall

jmp exit

printNoLeapYear:

poprax

movrsi, message1

movrdx, message1.length

xorrax, rax

movrax, 1                  ; system call 1 is write

movrdi, 1                  ; file handle 1 is stdout

syscall

jmp exit

printError:

;poprax

;movrsi, rax

movrsi, error

movrdx, error.length

;xorrax, rax

movrax, 1                  ; system call 1 is write

movrdi, 1                  ; file handle 1 is stdout

syscall

jmp exit

exit:

moveax, 60                 ; system call 60 is exit

xorrdi, rdi                ; exit code 0

syscall

; Input:

; RSI = pointer to the string to convert

; RCX = number of digits in the string (must be > 0)

; Output:

; RAX = integer value

string_to_int:

xorrbx,rbx    ; clear rbx

.next_digit:

movzxrax,byte[rsi]

incrsi

sub al,’0′    ; convert from ASCII to number

imul rbx,10

addrbx,rax   ; rbx = rbx*10 + rax

loop .next_digit  ; while (–rcx)

movrax,rbx

ret