Instructions
Objective
Write an ARM program Convert miles to kilometres in ARM assembly language.
Requirements and Specifications
- In the file libConversions.s you will implement two functions. Note the function signatures (order of arguments) must be maintained. Hours must be the first argument to kph!
- The first function is miles2kilometer(int miles), which will convert kilometers to miles by multiplying by 100 and dividing by 166. (Put in a comment why we multiply by 100, then divide by 166. Suggest how even greater precision could be achieved using this method for integer numbers).
- The second function is kph(int hours, int miles), and must be calculated by calling function miles2kilometers to convert the miles to kilometers, and then dividing by hours.
- Write an assembly language assignment program to prompt for and read the values of miles and hours, and print out the mph.
- Write the functions CToF and InchesToFt and add it to the conversions.s file. Write a main program to call it and test it.
Screenshots of output


Source Code
mainkph.s
# FileName: mainKph.s
# Author: ?????
# Date: 10/17/2022
# Purpose: Test the kph function in the libConversions library
.text
.global main
main:
# save return address in stack
SUB sp, sp, #4
STR lr, [sp, #0]
# prompt to enter hours
LDR r0, =prompth
BL printf
# read hours in stack
LDR r0, =format
SUB sp, sp, #4
MOV r1, sp
BL scanf
# load read number in r4
LDR r4, [sp, #0]
ADD sp, sp, #4
# prompt to enter miles
LDR r0, =promptm
BL printf
# read miles in stack
LDR r0, =format
SUB sp, sp, #4
MOV r1, sp
BL scanf
# load read number in r5
LDR r5, [sp, #0]
ADD sp, sp, #4
# make calculation
MOV r0, r4
MOV r1, r5
BL kph
# print result
MOV r1, r0
LDR r0, =result
BL printf
# load return address from stack
LDR lr, [sp, #0]
ADD sp, sp, #4
# return to os
MOV pc, lr
.data
prompth: .asciz "Enter the number of hours: "
promptm: .asciz "Enter the number of miles: "
format: .asciz "%d"
result: .asciz "The value of kph is: %d\n"
mainInchesToFt.s
# FileName: mainInchesToFt.s
# Author: ?????
# Date: 10/17/2022
# Purpose: Test the CtoF and InchesToFt functions in the libConversions library
.text
.global main
main:
# save return address in stack
SUB sp, sp, #4
STR lr, [sp, #0]
# prompt to enter celsius
LDR r0, =promptC
BL printf
# read celsius in stack
LDR r0, =format
SUB sp, sp, #4
MOV r1, sp
BL scanf
# load read number in r0
LDR r0, [sp, #0]
ADD sp, sp, #4
# make calculation
BL CtoF
# print result
MOV r1, r0
LDR r0, =resultF
BL printf
# prompt to enter inches
LDR r0, =promptI
BL printf
# read inches in stack
LDR r0, =format
SUB sp, sp, #4
MOV r1, sp
BL scanf
# load read number in r0
LDR r0, [sp, #0]
ADD sp, sp, #4
# make calculation
BL InchesToFt
# print result
MOV r1, r0
LDR r0, =resultFt
BL printf
# load return address from stack
LDR lr, [sp, #0]
ADD sp, sp, #4
# return to os
MOV pc, lr
.data
promptC: .asciz "Enter the number of celsius: "
promptI: .asciz "\nEnter the number of inches: "
format: .asciz "%d"
resultF: .asciz "The value of fahrenheit is: %d\n"
resultFt: .asciz "The value of feet is: %d\n"
libConversion.s
# FileName: libConversions.s
# Author: ?????
# Date: 10/17/2022
# Purpose: Conversion functions
.text
.global miles2kilometers
# Function: miles2kilometers
# Purpose: convert miles to kilometers
#
# Input: r0 - value in miles to convert
#
# Output: r0 - value converted to kilometers
miles2kilometers:
# save return address in stack
SUB sp, sp, #4
STR lr, [sp, #0]
# load value of 161 for multiplication
MOV r2, #161
# multiply miles * 161
MUL r0, r0, r2 # load value of 100 to make division
MOV r1, #100
# divide (miles * 161) / 100
BL __aeabi_idiv
# answer is in r0 so we can return it to caller
# We multiply times 100 in order to move the decimal point two positions
# to the left, the value of 161 is thus 1.61 * 100, 1.61 is the
# conversion of 1 mile to kilometers.
# The division by 100 is used to get the correct decimal point position:
# km = x mile * (161 km/mile) / 100 = x * 1.61 km
# If we need more precision we can multiply by a larger power of 10, for
# example 10000, thus the decimal point will be moved 4 positions to the left
# load return address from stack
LDR lr, [sp, #0]
ADD sp, sp, #4
# return to caller
MOV pc, lr
.global kph
# Function: kph
# Purpose: calculate kph from hours and miles
#
# Input: r0 - value of hours
# r1 - value of miles
#
# Output: r0 - result of calculation of kilometers per hour
kph:
# save return address and r4 in stack
SUB sp, sp, #8
STR lr, [sp, #0]
STR r4, [sp, #4]
# save hours argument in r4
MOV r4, r0
# convert miles to kilometers
MOV r0, r1
BL miles2kilometers
# km is in r0
# copy value of hours
MOV r1, r4
# divide km / hours
BL __aeabi_idiv
# answer is in r0 so we can return it to caller
# load return address and r4 from stack
LDR lr, [sp, #0]
LDR r4, [sp, #4]
ADD sp, sp, #8
# return to caller
MOV pc, lr
.global CtoF
# Function: CToF
# Purpose: convert celsius to fahrenheit
#
# Input: r0 - value of celsius
#
# Output: r0 - conversion to fahrenheit
CtoF:
# save return address in stack
SUB sp, sp, #4
STR lr, [sp, #0]
# load value of 900 for multiplication
MOV r2, #900
# multiply celsius * 900
MUL r0, r0, r2
# load value of 500 to make division
MOV r1, #500
# divide (celsius * 900) / 500
BL __aeabi_idiv
# answer is in r0
# add 32 to get answer
ADD r0, r0, #32
# load return address from stack
LDR lr, [sp, #0]
ADD sp, sp, #4
# return to caller
MOV pc, lr
.global InchesToFt
# Function: InchesToFt
# Purpose: convert inches to feet
#
# Input: r0 - value of inches
#
# Output: r0 - conversion to feet
InchesToFt:
# save return address in stack
SUB sp, sp, #4
STR lr, [sp, #0]
# load value of 12 to make division
MOV r1, #12
# divide inches / 12
BL __aeabi_idiv
# answer is in r0
# load return address from stack
LDR lr, [sp, #0]
ADD sp, sp, #4
# return to caller
MOV pc, lr