CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 8 of 8
  1. #1
    Join Date
    Oct 2005
    Location
    USA
    Posts
    22

    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?

  2. #2
    Join Date
    Nov 2005
    Posts
    21

    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.

  3. #3
    Join Date
    Oct 2005
    Location
    USA
    Posts
    22

    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?

  4. #4
    Join Date
    Nov 2005
    Posts
    21

    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.

  5. #5
    Join Date
    Oct 2005
    Location
    USA
    Posts
    22

    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?

  6. #6
    Join Date
    Oct 2005
    Location
    USA
    Posts
    22

    Exclamation 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?

  7. #7
    Join Date
    Apr 2003
    Posts
    1,755

    Smile 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.

  8. #8
    Join Date
    Oct 2005
    Location
    USA
    Posts
    22

    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
  •  





Click Here to Expand Forum to Full Width

Featured