gluestick
gluestick

Reputation: 88

How to print numbers greater then 10 in ARM200 Assembly language

We are using ARM200 to learn assembly language. I have a portion of memory with 32 integers filling it. I need to be able to print out these 32 integers to the screen. I can print out numbers 0 - 9 easy enough just by adding the ASCII value of the number 0 to what is in the register, but I'm very confused how you print out numbers greater then 9.

Print   LDR     r5, [r2]        ;load whats in that part of memory to r5.
        CMP     r5, #9      ;compare if number is greater or less then 9
       ADDLE    r0, r5, #"0"    ;add value in array to ascii value of 0 to print
       SWI  SWI_WriteC  ;Print Value    
       ADD  r6, r6, #1  ;increment counter
       ADD  r2, r2, #4  ;move portion of memory to the next int.
       CMP  r6, #32     ;check if you are done printing 32 ints
       BNE  Print       ;if not loop back up to print
       MOV  pc, r14     ;return

r0 is the register used for printing and r2 points to the location in memory for all the integers. r5 is what i put the value from memory into and r6 is used for a counter.
Yes i do realize that there is 4 bytes of space in between each number in memory, but this does not matter for this project.

Upvotes: 0

Views: 3717

Answers (2)

AusCBloke
AusCBloke

Reputation: 18492

You could do so with a simple loop, dividing your number by 10 and storing the remainder each time, until the number finally gets to 0. You'll basically end up with an array of numbers from 0-9 which you can then print one at a time. You have to store them before printing because you'll end up with each digit in reverse order. eg:

Number | Buffer
123    | { EMPTY }
12     | 3         (123 / 10 = 12, remainder 3)
1      | 3 2       (12 / 10 = 1, remainder 2)
0      | 3 2 1     (1 / 10 = 0, remainder 1)

Each time you add a number to the buffer, increment your counter. Once you've finished dividing and your number is now 0, you can then start printing. Loop from count to 0, printing out the number stored at Buffer + count.

For the buffer, if you're saying that each number can be up to 4 bytes (32 bits), than you know that in decimal the largest number that can be represented is either 2147483647 (signed) or 4294967295 (unsigned). In both cases, the largest most amount of digits is 10, so you can allocate a buffer of 10 bytes (1 byte is enough to hold each digit from 0-9).

Another alternative (which I've done before doing the same task as you for a different chip) is to use the stack rather than have a buffer allocated, and push each digit onto the stack at each iteration in the loop. Both ways are fairly simple.

I'll let you come up with the code, since you're meant to be learning how to do it.

Edit: This is some pseudo code of the common method I described above:

Buffer[10]

Num = 123

count = 0
// Split the number into an array of digits
WHILE Num IS NOT 0
   Buffer[count] = Num % 10 // Store the remainder
   Num = Num / 10
   count++

count-- // count will be 1 more than the amount in Buffer

// Print the digits
WHILE count IS >= 0
   PRINT Buffer[count]
   count--

Upvotes: 1

paxdiablo
paxdiablo

Reputation: 881623

Since you're learning (ie, possible homework), I'll give general advice only.

Let's say you have the number 247 and you wanted to print out the three digits of it, one by one.

How can you get the hundreds digit 2 from 247 and leave 47 for the next iteration?

Put that value into a temporary variable and set a counter to zero. Then, while the temp value is greater than 99, subtract 100 from it and add 1 to the counter.

This will give you a counter of 2 and a temp value of 47. Use the 2 to output your digit (you state you can already do this).

Now move on to tens.

Set the counter back to zero.

Then, while the temp value is greater than 9, subtract 10 from it and add 1 to the counter.

This will give you a counter of 4 and a temp value of 7. Use the 4 to output your digit.

Finally, units.

Use the final remainder 7 to output the last digit.


Here's some assembler-like pseudo-code I used in another answer (slightly modified) to do a similar thing.

    val = 247

    units = val
    tens = 0
    hundreds = 0
loop1:
    if units < 100 goto loop2
    units = units - 100
    hundreds = hundreds + 1
    goto loop1
loop2:
    if units < 10 goto done
    units = units - 10
    tens = tens + 1
    goto loop2
done:
    if hundreds > 0:                 # Don't print leading zeroes.
        output hundreds
    if hundreds > 0 or tens > 0:
        output tens
    output units
    ;; hundreds = 2, tens = 4, units = 7.

And one other thing, all this stuff needs to go into subroutines so that you can re-use them. Having thirty-two copies of that algorithm above converted to assembly would be a very tedious piece of code.

Upvotes: 1

Related Questions