|
-
November 8th, 2005, 11:47 PM
#1
convert decimal input to english text output
hey guys
i've been working on this one lab forever, and i just cannot get it right... actually, i can't even really start:
Lab Description:
You are to write an LC-3 program that accepts a decimal number from the user and prints the
English text equivalent of that number. The input number must be positive and between 0 and 99.
For example, if the user enters the numbers 2 and 4, then your program will print (send to the
display) the string “twenty-four”.
Hence this lab will focus on I/O operations (GETC, OUT, and PUTS) and arrays of characters
(known as “strings”) and arrays of pointers. It is important to distinguish between a value (such
as the number 3) and the character that represents is (such as the character ‘3’), between a value
and a pointer to that value, between a single character and a string.
Your code will have several “segments” or sections. Follow these directions for the appropriate
segments of your code:
1. Character input and echo:
- Write the code to prompt the user (with a “?”) to input a single decimal digit from the console.
Use the GETC routine to input a character, echo it to the console (so that the user sees what he
typed), and test whether it is a decimal digit (‘0’-‘9’).
− If the input character is a decimal number, then copy the character to R1.
− If the input character is a carriage return (ASCII x0A), branch/jump to a label called “DONE”.
This means you need not prompt for and convert any more inputs.
− If the input character is anything else, print “Ilegal Number”, and branch/jump to the beginning
and get another character.
2. ASCII-to-binary conversion:
After the character input code is (from segment 1 above) is executed, the ASCII code for a decimal
digit is in R1. Convert and replace this ASCII character with its corresponding binary number. In
other words, if R1 contains ASCII ‘2’ (0000 0000 0011 0010), make it contain the binary number 2
(0000 0000 0000 0010). Make sure your assembly language code works for all decimal digits.
3. Indexing into an array:
An array is a sequence of items of the same type and size. For example, you might have an array
of integers that represents the lab grades of all students in your section (89, 97, 15, 100, 99, 36,
99). The position that each item holds in an array is called its index. As always, we start counting
with zero, so the index of 89 in the above array is 0, the index of 97 is 1, and the index of the first
99 is 4. A common operation is to retrieve the i-th element of an array, given the index i.
Consider an array of integers that starts at location x4000, and R1 contains the index of an
element that you want to use. Write assembly language code to load that array element into R2.
(Assume that R1 is a “legal” index – that is, it is non-negative and less than the size of the array.)
Assume that your code will be loaded into the memory page starting with location x3000, so you
will not be on the same page as the array.
As mentioned earlier, you will write a program that prints the English text equivalent of a
decimal number between 0 and 99. Additional specifications are detailed below:
1. Print a prompt (“?”) to the console that signals the user to provide input. This can be very
simple, such as a question mark followed by a space.
2. Read characters from the keyboard and echo them to the console, until a complete legal input
is received. There are three kinds of legal input:
−−− A single decimal digit followed by a carriage return. This will be interpreted as a one-digit
decimal number.
−−− Two decimal digits followed by a carriage return. This will be interpreted as a two-digit
decimal number.
−−− A carriage return by itself. This will cause the program to terminate.
Any other input is illegal. An illegal input causes an error string to be printed, and
the program returns to the beginning prompt.
3. If a decimal number was input, print the English text equivalent, such as “zero”, “twelve”,
“sixty-four”, or “ninety”. Also print a carriage return after the string, so that the next prompt
appears on a new line.
4. After the text is printed, return to the beginning prompt.
You must use the GETC and OUT routines to input and echo the characters. You must use the
PUTS routine to print strings for the prompt, the error message, and the text output. (That does
not mean that a single PUTS must be used to print the text output.)
TIPS:
--- Consider what is the address of the data item that we wish to load? How can we compute that
address?
--- Consider which load instruction (addressing mode) should we use to move the data from
memory to R2?
--- You do not need to combine the ones’ digit and tens’ digit into a single binary value to
complete this program. The tens’ digit can be used to determine the first part of the text
output (e.g., “thirty”) and the ones’ digit can be used to determine the second part (e.g.,
“three”).
---- Make sure you properly deal with the following cases: zero, numbers between 11 and 19,
numbers that end in zero. Don’t forget the hyphen in numbers like ninety-nine.
--- A useful idea is to use the input value as an index into an array. Since an array assumes
that all elements are the same size, don’t put strings into the array – put pointers in the
array. In other words, let the i-th element of an array hold the address of a string, instead
of the string itself.
i have managed to write a few lines of code, mere segments of the assignments.. but i can't connect them, and i'm not even sure they work properly:
Code:
;routine to check that the magnitude of input is between 0 and 99.
RangeCheck LD R5,ZERO
ADD R4,R0,R5
BRp BAD
LD R5,NINETYNINE
ADD R4,R0,R5
BRn BAD
ADD R5,R5,0
RET
BAD ST R7,Save
LEA R0,ERROR
PUTS
LD R7,Save
AND R5,R5,#0
ADD R5,R5,#1
RET
ZERO .FILL #0
NINETYNINE .FILL #99
Save .FILL x0000
ERROR .FILL x000A
.STRINGZ "Error: Must be number between 0 and 99."
;input decimal digits from keyboard, convert ascii into binary, store binary values in successive memory locations
;starting at the address Binary.
LEA R3,Binary
LD R6,ASCII
AGAIN GETC
OUT
ADD R1,R1,R6
STR R1,R3,#0
ADD R3,R3,#1
ADD R7,R7,#-1
BRp AGAIN
BRnzp DONE
DONE HALT
ASCII .FILL xFFD0
Binary .BLKW #1
ur help will be much appreciated
If you choke a smurf, what color does it turn?
-
November 9th, 2005, 12:41 PM
#2
Re: convert decimal input to english text output
well,
i wont write the code for you
break it down into smaller parts. if you need to, wirte put what ou would do with this task in C or PERL or any other language. ie
1.) get input from user
2.) check to see that input is valid
-a) 0 to 99 means that it can only be 2 keystokes. (-1 keystroke for each backspace).
-b) The input has to be like this: [1 byte of data][1 bytes of data]
To check that, create a variable thats 2 bytes long, when the user hits a key, store the value of that key into variable. The next button press should go into varaible + 1 byte. (without checking for backspace).
-c) byte 1 and byte 2 should both be inbetween 30h and 39 hex. (easy, a few cmp, jg, jl statements)
3.) if byte 1 is 30, then your answer will be in the set {one two three four five six seven eight nine zero}
4.) if byte 1 is 31, then display the next byte, and tack on a 'teen'.
5.) if byte 1 is not 30h or 31h, display its value from the set {twenty, thirty, etc}
6.) Display the next byte from the set {one two three}
hope this helps.
-
November 9th, 2005, 08:09 PM
#3
Re: convert decimal input to english text output
hmm well first, i wasn't asking for someone to write the code for me, because i'm an engineering major, i need to understand this stuff rather than simply cheat so i can excel in my other courses.
second, most of what ur talking about is stuff i don't really know how to do. i've only programmed in java before, which is quite different, and it was merely an intro class -- so that's no good. i understand the logic ur suggesting, but i don't know how to go about it.
anyway, i will try and post my resulting code soon.
thanks
Last edited by caramel; November 9th, 2005 at 08:19 PM.
If you choke a smurf, what color does it turn?
-
November 10th, 2005, 11:10 AM
#4
Re: convert decimal input to english text output
I wont use windows or linux system calls, i use interupts instead.
Im not on MY computer now, so all the code my not be correct, but at least it will give you something to work with. I know the headers are wrong.
I use TASM
Code:
.model TINY
ORG 100h
.DATA
welcome db "Input a 2 digit number:", 0Ah, 0Dh, '$'
notnumber db "That is not a number 0-9", 0Ah, 0Dh, '$'
tens db 0h
ones db 0h
thirty db "THIRTY-$"
.CODE
start:
;prompt the user for a 2 digit number
mov ah, 9h
mov dx, OFFSET welcome
int 21h
FIRST_NUMBER:
;input the first number
mov ah, 1h
int 21h
;the number is now stored in al
cmp al, 30h
jl NOT_NUMBER
cmp al, 39h
jg NOT_NUMBER
;first number is between 0 and 9. store it
mov bx, OFFSET tens
mov [bx], al
SECOND NUMBER
mov ah, 1h
int 21h
;the number is now stored in al
cmp al, 30h
jl NOT_NUMBER
cmp al, 39h
jg NOT_NUMBER
mov bx, OFFSET ones
mov [bx], al
;you now have their two numbers (you should also check for backspace, i dont know what the hex value is, but just use
;cmp al, <value for backspace key>h
;je FIRST_NUMBER. you could also clear the input by moving the cursor to ;that space and then outputing " " there...
;handle the numbers
I have to go, but handling the numbers would be like this:
Code:
HANDLETENS:
mov bx, OFFSET tens
mov al, [bx]
cmp al, 32h
je DISPLAY_TWENTY
cmp al, 33h
je DISPLAY_THIRTY
...........
...........
DISPLAY_THIRTY
mov ah, 9h
mov dx, OFFSET thirty
int 21h
jmp HANDLEONES
Thats an example of thirty, you should be able to pick up on the pattern
Code:
NOT_NUMBER:
mov ah, 9hA
mov dx, OFFSET notnumber
int 21h
jump start
ENDP start
Now you should take the time to make this code more efficiant - with macros and procedures. Like inputting a number and then checking it, should be a macro or a proc, whatever you see fit.
-
November 10th, 2005, 12:27 PM
#5
Re: convert decimal input to english text output
the code u posted is simply foreign to me... i'm programming in lc-3 assembly language, i'm not even really sure what u mean by ur samples of code. but i read ur comments within the program, and i will go from there, hopefully that'll help me out a bit
If you choke a smurf, what color does it turn?
-
November 11th, 2005, 07:50 PM
#6
Re: convert decimal input to english text output
well here's the code i ended up with:
Code:
; Take sequence of ASCII digits typed by user, call ASCIItoBinary subroutine for conversion, push binary value onto
; stack.
.ORIG x3000
INPUT LEA R0,PROMPT ;load prompt
PUTS ;display prompt
GETC ;read number
OUT ;display number
BRnzp RangeCheck
PUSH LEA R1,ASCIIBUFF ;R1 points to string being
LD R2,MAX ;generated
VALUE ADD R3,R0,xFFF6 ;test for carriage return
BRz GOOD
ADD R2,R2,#0
BRz TooLarge
ADD R2,R2,#-1 ;read more digits
STR R0,R1,#0 ;store last character read
ADD R1,R1,#1
GETC
OUT ;echo
BRnzp VALUE
GOOD LEA R2,ASCIIBUFF
NOT R2,R2
ADD R2,R2,#1
ADD R1,R1,R2 ;R1 contains number of characters
JSR ASCIItoBinary
JSR PUSH
BRnzp INPUT
TooLarge GETC ;loop until return
OUT
ADD R3,R0,xFFF6
BRnp TooLarge
BRnzp INPUT
;ASCIItoBinary conversion
ASCIItoBinary AND R0,R0,#0 ;R0 contains result
ADD R1,R1,#0 ;test number of digits
BRz END ;no digits,terminate
LD R3,NEGOFF ;R3 gets xFFD0
LEA R2,ASCIIBUFF
ADD R2,R2,R1
ADD R2,R2,#-1 ;R2 points to ones place
LDR R4,R2,#0 ;load ones digit in R4
ADD R4,R4,R3 ;strip off ASCII template
ADD R0,R0,R4 ;add ones digit
ADD R1,R1,#-1
BRz DONE ;original number had one digit
ADD R2,R2,#-1 ;R2 points to tens place
LDR R4,R2,#0 ;R4 contains tens digit
ADD R4,R4,R3 ;strip off ASCII template
LEA R5,TENS ;tens values
ADD R5,R5,R4 ;R5 points to correct tens value
LDR R4,R5,#0
ADD R0,R0,R4 ;add tens value to total
ADD R1,R1,#-1
BRz DONE ;number consists of two digits
DONE RET
;routine to check that the magnitude of input is between 0 and 99.
RangeCheck LD R5,ZERO
ADD R4,R0,R5 ;R0 contais result being
BRp BAD ;checked
LD R5,NINETYNINE
ADD R4,R0,R5
BRn BAD
ADD R5,R5,0 ;R5 <- within range
RET
BAD ST R7,Save ;save R7
LEA R0,ERROR
PUTS ;display error msg
LD R7,Save
AND R5,R5,#0
ADD R5,R5,#1 ;R5 <- out of range
BRnzp INPUT
END HALT
PROMPT .FILL x000A
.STRINGZ "?"
MAX .FILL x0003
NEGOFF .FILL xFFD0
ASCIIBUFF .BLKW 4
TENS .FILL #0
.FILL #10
.FILL #20
.FILL #30
.FILL #40
.FILL #50
.FILL #60
.FILL #70
.FILL #80
.FILL #90
ZERO .FILL #0
NINETYNINE .FILL #99
Save .FILL x0000
ERROR .FILL x000A
.STRINGZ "Error: Number must be between 0 and 99."
.END
i still don't know how to make the array, and i'm also confused on converting binary into english text to be displayed (i'm assuming this is done through the array).... also, it reports that number is out of range no matter what the input is... any suggestions?
Last edited by caramel; November 11th, 2005 at 08:56 PM.
If you choke a smurf, what color does it turn?
-
November 12th, 2005, 02:18 AM
#7
Re: convert decimal input to english text output
HI caramel, here's the code. It may not follow exactly the instruction given but you can start from it. I commented it as much as I can for you to understand.
Code:
.ORIG x4000
START AND R6, R6, #0 ;init R6 (will hold the input value)
LEA R0, s_qmark ; print "?"
PUTS
ASKCHAR GETC ; getchar
ADD R5, R0, #-10 ; if == 0x0D (ENTER), then goto DONE
BRz DONE
ADD R5, R6, #-10 ; if R6 >= 10, dont accept any input except ENTER
BRzp ASKCHAR
LD R1, neg_ch9 ; is it <= '9'? if no, goto BAD
ADD R5, R0, R1
BRp BAD
LD R1, neg_ch0 ; is it >= '0'? if no, goto BAD
ADD R5, R0, R1 ; R5 will also hold the converted value
BRn BAD
PUTC ; output the character
; in here, we will multiply the current value of R6 by 10
; then add the new character value. We do the multiplication by
; adding the original R6 value 10 times (loop)
AND R1, R1, #0 ; initialize this will be out COUNTER
ADD R0, R6, #0 ; save the orig R6 value to R0
BRz ADD_VAL ; if R0 is currently 0, we dont need to multiply
LOOPMUL ADD R1, R1, #1 ; increment our counter
ADD R2, R1, #-10 ; is it == 10? if yes, go add the new char value
BRz ADD_VAL
ADD R6, R6, R0 ; this is added 10x
BR LOOPMUL
ADD_VAL ADD R6, R6, R5 ; add the new character value
BR ASKCHAR ; ask another character
BAD LEA R0, s_ill ; if wrong char, show error
PUTS
BR START ; and jump to the very start
DONE ADD R0, R6, #0 ; if input is 0 or blank, we EXIT
BRz EXIT
LEA R0, s_lf ; if done, go to the next line
PUTS
LD R0, neg_19 ; check if it's <= 19
ADD R0, R6, R0
BRnz LESS_20
; this will print the 10s value 20, 30, 40, 50, 60, 70, 80, 90
AND R1, R1, #0 ; init these registers, we will use them
AND R4, R4, #0
AND R5, R5, #0 ; R5 will hold the 10s values
ADD_10 ADD R4, R4, #-10 ; add -10 in ever loop
ADD R5, R5, #1 ; increment our 10s COUNTER
ADD R0, R6, R4 ; check the INPUT with R4
BRz OUT_10 ; and if 0 (zero) go print them now
BRp ADD_10 ; if still not enough, loop
ADD R5, R5, #-1 ; if not exact, subtract 1 (the excess)
ADD R4, R4, #10 ; same with your R4 (value of 10)
OUT_10 LEA R0, arr_ten ; get address of table
ADD R0, R0, R5 ; add the index value (from the ADD_10)
LDR R0, R0, #-2 ; load the string
; -2 bec table start with "twenty" (20/10)
PUTS ; and print it
LEA R0, s_ty ; print "ty" (in e.g. "twen" + "ty")
PUTS
ADD R6, R6, R4 ; check if the remainder is 0
BRz FINISH ; and goto FINISH
LEA R0, s_dash ; print "-"
PUTS
LESS_20 LEA R0, arr_num ; the the table for 0 - 19
ADD R0, R0, R6 ; add the index
LDR R0, R0, #-1 ; and load the value to R0 the print
; -1 again because we started from "one"
PUTS
ADD R0, R6, #-12 ; is it > 12? (we need the "teen")
BRnz FINISH
LEA R0, s_teen ; print "teen" for 13 - 19
PUTS
FINISH LEA R0, s_lf ; print <lf>
PUTS
BR START ; go to the very start
EXIT HALT
neg_ch0 .FILL 0xFFD0 ;'0' (negative)
neg_ch9 .FILL 0xFFC7 ;'9' (negative)
neg_19 .FILL 0xFFED ;-19
s_qmark .STRINGZ "? "
s_dash .STRINGZ "-"
s_lf .STRINGZ "\n"
s_ty .STRINGZ "ty"
s_teen .STRINGZ "teen"
s_ill .STRINGZ "\nIlegal Number\n"
arr_num .FILL s_1
.FILL s_2
.FILL s_3
.FILL s_4
.FILL s_5
.FILL s_6
.FILL s_7
.FILL s_8
.FILL s_9
.FILL s_10
.FILL s_11
.FILL s_12
.FILL s_13
.FILL s_14
.FILL s_15
.FILL s_16
.FILL s_17
.FILL s_18
.FILL s_19
arr_ten .FILL s_20
.FILL s_30
.FILL s_40
.FILL s_50
.FILL s_60
.FILL s_70
.FILL s_80
.FILL s_90
s_1 .STRINGZ "one"
s_2 .STRINGZ "two"
s_3 .STRINGZ "three"
s_4 .STRINGZ "four"
s_5 .STRINGZ "five"
s_6 .STRINGZ "six"
s_7 .STRINGZ "seven"
s_8 .STRINGZ "eight"
s_9 .STRINGZ "nine"
s_10 .STRINGZ "ten"
s_11 .STRINGZ "eleven"
s_12 .STRINGZ "twelve"
s_13 .STRINGZ "thir"
s_14 .STRINGZ "four"
s_15 .STRINGZ "fif"
s_16 .STRINGZ "six"
s_17 .STRINGZ "seven"
s_18 .STRINGZ "eigh"
s_19 .STRINGZ "nine"
s_20 .STRINGZ "twen"
s_30 .STRINGZ "thir"
s_40 .STRINGZ "four"
s_50 .STRINGZ "fif"
s_60 .STRINGZ "six"
s_70 .STRINGZ "seven"
s_80 .STRINGZ "eigh"
s_90 .STRINGZ "nine"
.END
Hope it will help you
Last edited by rxbagain; November 12th, 2005 at 11:34 AM.
-
November 16th, 2005, 12:32 AM
#8
Re: convert decimal input to english text output
thanks so much for the help, rx.. i've already turned in the assignment though, and it generaly worked out ok, with few exceptions.. so i will not get a perfect score, but at least i'll get a decent grade
but thanks once more, i appreciate it
If you choke a smurf, what color does it turn?
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|