Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

Write a MARIE assembly language program that calculates and displays the perimet

ID: 672486 • Letter: W

Question

Write a MARIE assembly language program that calculates and displays the perimeter or the area of a rectangle, given the length of each side, depending on the user’s input.

The user should be prompted to enter the length of each of the sides; once these values have been read by the program, provide the user with the options to select which calculation to perform on the rectangle, and prompt them to enter one of the options.

For example: Enter Perimeter(P) or Area(A)

The application should accept a character corresponding to one of the actions: P for Perimeter or A for Area. The output statements should accurately describe the results being displayed. For example, if the input is:

4 (for one side)

5 (for the other side)

A (for calculation type)

Your program should print something like this: The area of the rectangle is 20.

Explanation / Answer

Solution :

.data

;The limit for each dimension is 2 digits (max 99*99) because otherwise the answer might be too big for the 16 register to hold

msg byte 0dh, 0ah, 0dh, 0ah, "Demonisch Rectangle area calculator", 0dh, 0ah, "Each dimension can be up to two digits long", 0dh, 0ah, "$"

msgWid byte 0dh, 0ah, "Width: $"

msgHei byte 0dh, 0ah, "Height: $"

msgDim byte 0dh, 0ah, "The area of the rectangle is: $"

msgEnd byte 0dh, 0ah, 0dh, 0ah, "Press any key to continue", 0dh, 0ah, 0dh, 0ah, "$"

wid word 0000h

.code

main PROC

mov ax, SEG msg

mov ds, ax

mov ah, 9

mov dx, OFFSET msg ;Show header message

int 21h

getWid:

mov ah, 9

mov dx, OFFSET msgWid ;Ask for width

int 21h

call getNum ;Call function getNum(), returns entered num in bx

cmp bx, 0000h ;If an error occured getNum() returns 0, not a valid dimension so get another number

je getWid

mov wid, bx ;Store the width

getHei:

mov ah, 9

mov dx, OFFSET msgHei

int 21h

call getNum

cmp bx, 0000h

je getHei

mov ax, bx ;ax stores the height

mov cx, wid ;cx stores the width, which is used to know how many times to loop

mov bx, 0000h ;Reset bx to 0 so it can be added to

mulAns:

add bx, ax ;Keep adding the height to itself

dec cx

cmp cx, 0000h ;Until width is 0

jg mulAns

disAns:

mov ah, 9

mov dx, OFFSET msgDim

int 21h

call disNum

proEnd:

mov ah,9

mov dx,OFFSET msgEnd

int 21h

mov ah, 1 ;Wait for any key, allows the user to read any output

int 21h ;before the programme ends and the window closes

mov ah, 4ch

int 21h

main ENDP

;-----------------------------------------------------------------------------------

getNum PROC

.data

msgBN byte " [Only enter digits]$"

msgZ byte " [Zero number not allowed]$"

numIn word 0000h

.code

push ax ;This sub requires bx to pass the number back

push cx ;But everything else can be reserved

push dx

push si

push di

readNumS: ;Start

mov cx, 0000h

mov numIn, 0000h ;Reset the values, otherwise repeated calls to this function will use the last stored values

readNumG: ;Get

mov ah, 8 ;Silent read mode, does not echo to the screen

int 21h

mov bx, 0000h

mov bl, al

cmp bl, 0Dh ;Return

je readNumF

cmp bl, 30h ;0 (ASCII 48)

jl badNum

cmp bl, 39h ;9 (ASCII 57)

jg badNum

mov ah, 6 ;Char display mode

mov dl, bl

int 21h ;Display the entered char

sub bl, 30h ;Turn into digit

mov dx, numIn

mov ax, dx

mov ch, 00h

readNumL: ;Loop ten times, moving all the digits in the current numIn 1 place forward (effectively * 10)

add ax, dx

inc ch

cmp ch, 09h

jl readNumL

add ax, bx

mov numIn, ax

inc cl

cmp cl, 02h ;Only allow 2 digit numbers

jl readNumG

readNumF:

cmp numIn, 0000h ;Do not accept the number 0

je zeroNum

mov bx, numIn

readNumE:

pop di ;Returns all of the registers apart from bx to there original states

pop si

pop dx

pop cx

pop ax

ret

;Errors

zeroNum:

mov ah, 9

mov dx, OFFSET msgZ

int 21h

mov bx, 0000h

jmp readNumE

badNum: ;Digit was expected but not entered

mov ah, 6 ;Display the offending character

mov dl, al

int 21h

mov ah, 9

mov dx, OFFSET msgBN

int 21h

mov bx, 0000h

jmp readNumE

getNum ENDP

;--------------------------------------------------------------------------------;

disNum PROC

.data

numOut word 0000h

.code

mov numOut, bx ;Store a copy before pushing, so the original after this method stays the same

push ax

push bx

push cx

push dx

push si

push di

mov bx, numOut ;Use this copy

disNumF:

mov cl, 00h

cmp bx, 03E8h ; 1000

jge getThou

cmp bx, 0064h ; 100

jge getHun

cmp bx, 000Ah ; 10

jge getTen

jmp disUnit

getThou:

inc cl

sub bx, 3E8h

cmp bx, 3E8h

jge getThou

disThou:

add cl, 30h

mov ah, 6

mov dl, cl

int 21h

mov dl, 2Ch ;Display thousand comma

int 21h

mov cl, 00h

cmp bx, 64h

jl disHun

getHun:

inc cl

sub bx, 64h

cmp bx, 64h

jge getHun

disHun:

add cl, 30h

mov ah, 6

mov dl, cl

int 21h

mov cl, 00h

cmp bx, 0Ah

jl disTen

getTen:

inc cl

sub bx, 0Ah

cmp bx, 0Ah

jge getTen

disTen:

add cl, 30h

mov ah, 6

mov dl, cl

int 21h

mov cl, 00h

cmp bx, 01h

jl disUnit

disUnit:

add bl, 30h

mov ah, 6

mov dl, bl

int 21h

pop di ;Restore previous values, most importantly bx in case the user wants to use that number again

pop si

pop dx

pop cx

pop bx

pop ax

ret

disNum ENDP

;--------------------------------------------------------------------------------;

END main

Hire Me For All Your Tutoring Needs
Integrity-first tutoring: clear explanations, guidance, and feedback.
Drop an Email at
drjack9650@gmail.com
Chat Now And Get Quote