# Creating an assembly code that determines leap years

Our programming experts are well versed in assembly language. In this article, they outline the various steps that one should use to create an assembly code that determines whether a year is a leap year or not.

## 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
▪ Take​ ​a​ ​4-digit​ ​string
▪ Get​ ​the​ ​thousands​ ​digit
▪ Multiply​ ​by​ ​10
▪ 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 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

pushrax ; save year

xorrdx, rdx

div qword [hundred] ; divide year by 100

cmprdx, 0

jzprintNoLeapYear ; if divisible 100 it is not a leap 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