EASy68K  
It is currently Sat Jun 06, 2020 8:48 am

All times are UTC




Post new topic Reply to topic  [ 21 posts ]  Go to page 1, 2  Next
Author Message
PostPosted: Wed Jan 18, 2006 10:34 pm 
Offline

Joined: Wed Jan 18, 2006 10:07 pm
Posts: 11
Hi! I have a problem that i cannot solve and it must be solved yesterday :)

Anyway, i have an assignment for school where i have to add four 32-bit numbers with 64-bit precision, and then output that number to the output window in the simulator. I have to somehow convert the number to ascii and i don't have a clue (ok i do but it's a very very complicated and i'm not that skilled in asm).

Anyway i have this code, and it calculates the number but it's only in memory somewhere around the $2400 to 2403. The result is ok i think, but i cant print it in the output window. Can anybody help me (and perhaps solve the problem for me :))

This is my code:

Code:
START   ORG   $1000


      * Ispis "Unesi prvi broj: " i spremi unos u D1
      MOVE #18, D0
          LEA prvi, A1
          TRAP #15

      MOVE.L D1, D3
      clr   D1

      * Ispis "Unesi drugi broj: " i spremi unos u D1
      MOVE #18, D0
          LEA drugi, A1
          TRAP #15

      MOVE.L D1, D4
      clr   D1

      * Ispis "Unesi treci broj: " i spremi unos u D1
      MOVE #18, D0
          LEA treci, A1
          TRAP #15

      MOVE.L D1, D5
      clr   D1

      * Ispis "Unesi cetvrti broj: " i spremi unos u D1
      MOVE #18, D0
          LEA cetvrti, A1
          TRAP #15

      move.l D1, D6
      clr   D1


      JMP Zbroji

   
Zbroji      * Premjesti unesene rezultate iz registara u memoriju
      move.l  D3, TempLong
      move.l  D4, temp1

      * Stavi pointere na varijable radi lakseg snalazenja i dodaj im pomak od 4 bajta
      * zbog potrebe predecrement address-register deferred mode koji koristi addx naredba
      * za dodavanje dvaju mem. lokacija   
      lea    temp1(PC), A2
      add   #4, A2
      lea    temp2(PC), A3
      add   #4, A3
      lea    TempLong(PC), A4
      add     #4, A4
      lea    Result(PC), A5
      add    #4, A5

      * Prvo smanji adrese u A2 i A4 za jedan bajt (zato jer koristim addx.b), tako dohvatim najmanje znacajne bajtove
      * u temp1 i TempLong varijablama i dodajem ih zajedno skupa s prijenosom ako ga ima itd.
      * i to tako 8 puta (jer je 8x8 64 bita, a treba mi 64 bitna preciznost ^_^).
      * Rezultat se spremi u TempLong varijabli.
      addx.b   -(A2), -(A4)
      addx.b   -(A2), -(A4)
      addx.b   -(A2), -(A4)
      addx.b   -(A2), -(A4)
      addx.b   -(A2), -(A4)
      addx.b   -(A2), -(A4)
      addx.b   -(A2), -(A4)
      addx.b   -(A2), -(A4)

      * Pocisti za sobom
      clr  D3
      clr  D4

      move.l  D5, Result
      move.l  D6, temp2
   

      * Prvo smanji adrese u A3 i A5 za jedan bajt, tako dohvatim najmanje znacajne bajtove
      * u temp2 i Result varijablama i dodajem ih zajedno skupa s prijenosom ako ga ima itd.
      * i to tako 8 puta. Rezultat se spremi u Result varijabli.

      addx.b   -(A3), -(A5)
      addx.b   -(A3), -(A5)
      addx.b   -(A3), -(A5)
      addx.b   -(A3), -(A5)
      addx.b   -(A3), -(A5)
      addx.b   -(A3), -(A5)
      addx.b   -(A3), -(A5)
      addx.b   -(A3), -(A5)

      clr  D5
      clr  D6

      * Ponovno postavi pokazivace na TempLong i Result varijable jer su prijasnje operacije to poremetile.
      * Takodjer ih povecaj za 4

      lea    TempLong(PC), A4
      add     #4, A4
      lea    Result(PC), A5
      add    #4, A5

      * Prvo smanji adrese u A4 i A5 za jedan bajt, tako dohvatim najmanje znacajne bajtove
      * u TempLong i Result varijablama i dodajem ih zajedno skupa s prijenosom ako ga ima itd.
      * i to tako 8 puta. Rezultat se spremi u Result varijablu.

      addx.b   -(A4), -(A5)
      addx.b   -(A4), -(A5)
      addx.b   -(A4), -(A5)
      addx.b   -(A4), -(A5)
      addx.b   -(A4), -(A5)
      addx.b   -(A4), -(A5)
      addx.b   -(A4), -(A5)
      addx.b   -(A4), -(A5)

      * Rezultat se mora iscitati u memoriji negdje oko lokacije $2400

      *lea    ASCIResult(PC), A4
      *add   #4, A4

      *na lošem putu sam!

      *move.b (A5)+, D5


      *cmp.b  #00, D5
      *beq   dodaj1



      move.l Result, D1

          MOVE #14, D0
          LEA Rezultat, A1
          TRAP #15


      
      * Prikazi rezultat zbrajanja
      MOVE #20, D0
      MOVE.B #14, D2
      TRAP #15


      jmp Kraj
      

Kraj          stop #$3000

dodaj1      move.b  #48, (A4)+


      ORG $2600
Rezultat   dc.b 'Rezultat zbrajanja je: ', 0
prvi       dc.b 'Unesi prvi broj: ', 0
drugi       dc.b 'Unesi drugi broj: ',0
treci       dc.b 'Unesi treci broj: ', 0
cetvrti    dc.b 'Unesi cetvrti broj: ',0

      ORG $2300
temp1       ds.l 1
      ORG $2310
temp2      ds.l 1

      ORG $2400
Result      ds.l  2
      ORG $2500
TempLong   ds.l  2

      ORG $2200
ASCIResult   dc.l  2



      END   START


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 19, 2006 3:13 am 
Offline

Joined: Tue Nov 15, 2005 7:58 am
Posts: 129
Location: Oregon, USA
Well, I don't want to do your assignment for you, and in fact I didn't even read all your program. But I can give you a couple of hints. You get to write the actual 68000 code. :lol:

#1 - Use loops for repeated actions (in this case, inputting and adding the numbers). I see from your code you know about branches (Bcc). Also consider the DBcc instruction family.

#2 - Convert binary numbers first to BCD (Binary-Coded Decimal, one 0-9 binary number per byte) by repeatedly dividing by ten. Each time you divide, the remainder is one BCD digit. Then convert the BCD digits to ASCII by adding (or ORing, it doesn't matter) ASCII "0" ($30) to each. This should be another loop. You'll then need to print the resulting ASCII digits in the opposite order, also using a loop.

Example: convert $1234 to BCD:
$1234 / 10. = $01D2, remainder is $00
$01D2 / 10. = $002E, remainder is $06
$002E / 10. = $0004, remainder is $06
$0004 <= 10. so no need to actually divide,
next remainder would be $04

Add $30 to each gives $30, $36, $36, $34 = "0664"

Reverse order = "4660", which is decimal for $1234.

This is a 16-bit example, but it works the same way for any size binary number.

It also works about the same way for other conversions; for instance, to convert to ASCII octal you'd just divide by 8 instead of 10.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 19, 2006 11:49 pm 
Offline

Joined: Mon Dec 27, 2004 11:40 pm
Posts: 318
If, instead of doing divide by 10, you do divide by n at each stage you can output the number in any base you wish.

To convert each digit to ASCII simply use the digit value to access an array of ASCII characters. E.g. this is the table I use in my binary to base n conversion routine

Code:
   dc.b   '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'

Also if you use a pre decrement address mode to save each character to a buffer the order is reversed im memory for free.

Code:
   MOVE.b   (a0,d0.w),-(a1)      * put character into numeric buffer

If, after each divide, the result of the divide is tested for zero the loop can exit early leaving the pointer, in this case a1, pointing to the first character of a leading zero supressed result. If a fixed length result is required it is simply a case of filling the buffer with '0' characters before the conversion starts.

Code:
   TST.l         d1            * test result of divide
   BNE.s      div_n_loop         * loop if more dividing to do


Lee.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jan 20, 2006 12:34 am 
Offline

Joined: Wed Jan 18, 2006 10:07 pm
Posts: 11
Thanks for the answers. I've got a couple of questions though, if i have the result stored in memory i can't use DIV because the number must be located in a data register.

Is there some other method for calculating 64bit numbers other than what i posted here? More importantly, is my code a good way to do the calculation, that is am i calculating it right or i just kinda guessed it, and the code does nothing :)

It should be ok cause i get a good result (but i can only add unsigned numbers), so how do i get it to fit into a register or two...

Thanks!

PS: Sorry for the foreign comments but i think you can see what i'm doing in the code


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jan 20, 2006 2:52 am 
Offline

Joined: Mon Dec 27, 2004 11:40 pm
Posts: 318
Velorien wrote:
if i have the result stored in memory i can't use DIV because the number must be located in a data register.

Then move the number from memory to a data register first

Quote:
Is there some other method for calculating 64bit numbers other than what i posted here?

There are many many ways of doing just about anything in assembler.

Quote:
More importantly, is my code a good way to do the calculation, that is am i calculating it right or i just kinda guessed it, and the code does nothing :)

If it does what was asked then it is right, after that it's just style. 8^)=

Quote:
It should be ok cause i get a good result (but i can only add unsigned numbers)

Signed and unsigned numbers are the same and if your program can add one type it can add the other. It's only when you decide what all those 1's and 0's mean that signed becomes different.

Quote:
, so how do i get it to fit into a register or two...

Don't move it out of the register in the first place. If you have two data registers you can hold a 64 bit number in them.

Quote:
PS: Sorry for the foreign comments but i think you can see what i'm doing in the code

It's only foreign if you don't speak Croatian (I'm guessing).

Lee.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jan 20, 2006 10:27 am 
Offline

Joined: Wed Jan 18, 2006 10:07 pm
Posts: 11
Yes it's Croatian :)

Anyway, i've moved it to two data registers, and lets say that my result is 16000000000. I've got the upper 32 bits in D4, and lower in D5. That's 3B9ACA000, 3 is in D4 and the rest is in D5.

So how do i convert it to ascii? I if i divide B9ACA000 with 10 i'll get some number that isn't a good result because i need the 3, if i multiply the 3 with 16^8 i'll get a number thats too big to a register and so on and so on :)

Anyway, i don't how to represent a 64bit number with two 32 bit numbers or how do i put it, but i think you'll understand what i mean :)


Top
 Profile  
 
 Post subject:
PostPosted: Sat Jan 21, 2006 12:27 am 
Offline

Joined: Tue Nov 15, 2005 7:58 am
Posts: 129
Location: Oregon, USA
If this is a class assignment (as it appears to be), could you tell us what techniques you are supposed to have learned that you should be applying to this problem? Generally, such assignments are given to reinforce whatever was most recently taught...

Specifically, has "multiple precision arithmetic" been covered? Software division algorithms? Use of the condition code flags? Binary coded decimal? Indexing?

Do you have access to (paper) textbooks with algorithms and sample programs? Have you done a Web search (e.g. Google) for relevant code snippets? Checked Freescale's web site? Looked at Lee's EHBASIC68K code, which you can find the same place you found EASy68K?


Top
 Profile  
 
 Post subject:
PostPosted: Sat Jan 21, 2006 12:52 am 
Offline

Joined: Mon Dec 27, 2004 11:40 pm
Posts: 318
Velorien wrote:
I if i divide B9ACA000 with 10 i'll get some number that isn't a good result because i need the 3, if i multiply the 3 with 16^8 i'll get a number thats too big to a register and so on and so on :)

You have to do it like long division dividing successive longwords by word divisors. It goes something like this..

Code:
         |       64 bit very long word       |
                  |                 |
                  V                 V
         | 32 bit longword | 32 bit longword |
             |        |        |        |
             V        V        V        V
         | word A | word B | word C | word D |   word A always $0000
                      |        |        |
                      V        V        |
                  | word B | word C |   |
divide by                  |     10 |   |
                  -------------------   |
                  | remain | result |   |
swap words                              |
                  |result h| remain |   |
                      |        |        |
                      |        V        V
                      |    | remain | word D |
divide by             |             |     10 |
                      |    -------------------
                      |    | remain |result l|
swap words            |
                      |    |result l| remain | -> remainder is digit
                      |        |
                      V        V
         | $0000  |result h|result l|
             |        |        |
             V        V        V
| word A | word B | word C | word D |   for next divide

In assembly this will involve a few SWAP and MOVE.w and a couple of DIVU instructions.

The final remainder is the binary digit 0 to 9 that needs to be converted to decimal and the result feeds back into the longword for the next division to get the next digit.

Hope that help some.

Lee.


Top
 Profile  
 
 Post subject:
PostPosted: Sat Jan 21, 2006 1:04 am 
Offline

Joined: Wed Jan 18, 2006 10:07 pm
Posts: 11
Hi,

Quote:
Specifically, has "multiple precision arithmetic" been covered? Software division algorithms? Use of the condition code flags? Binary coded decimal? Indexing?


The answer is no. The assistent for the class "Computer Architectures" showed us the basics (move, add...) and said RTFM and that was it.

I have no textbooks nor sample programs. I've searched Google but found nothing for M68k so i've checked x86 asm examples. I've found multiple precision addition examples and i've tried to convert it for M68k with no luck. Then i remembered that Motorola uses High Endian, reversed the order of the additions (originaly i added from ho bytes to low) and it worked.

I don't know about Freescale's web site, and i'll try and look into the EHBASIC code but this is kinda urgent so i tried to get a faster answer here.

Anyway, up till now i've managed to output the result in hexadecimal, with some tricks ofcourse (i used the Task #15 on both registers :)), but i don't think it'll be enough.

Were the first generation of students that has this kind of assignment, and most of my classmates are clueless when it comes to asm so i can't ask them or any of the senior students. This is some kind of (sick :P) experiment at the colledge i'm attending :)


Top
 Profile  
 
 Post subject:
PostPosted: Sat Jan 21, 2006 1:10 am 
Offline

Joined: Wed Jan 18, 2006 10:07 pm
Posts: 11
lee wrote:
Velorien wrote:
I if i divide B9ACA000 with 10 i'll get some number that isn't a good result because i need the 3, if i multiply the 3 with 16^8 i'll get a number thats too big to a register and so on and so on :)

You have to do it like long division dividing successive longwords by word divisors. It goes something like this..

Code:
         |       64 bit very long word       |
                  |                 |
                  V                 V
         | 32 bit longword | 32 bit longword |
             |        |        |        |
             V        V        V        V
         | word A | word B | word C | word D |   word A always $0000
                      |        |        |
                      V        V        |
                  | word B | word C |   |
divide by                  |     10 |   |
                  -------------------   |
                  | remain | result |   |
swap words                              |
                  |result h| remain |   |
                      |        |        |
                      |        V        V
                      |    | remain | word D |
divide by             |             |     10 |
                      |    -------------------
                      |    | remain |result l|
swap words            |
                      |    |result l| remain | -> remainder is digit
                      |        |
                      V        V
         | $0000  |result h|result l|
             |        |        |
             V        V        V
| word A | word B | word C | word D |   for next divide

In assembly this will involve a few SWAP and MOVE.w and a couple of DIVU instructions.

The final remainder is the binary digit 0 to 9 that needs to be converted to decimal and the result feeds back into the longword for the next division to get the next digit.

Hope that help some.

Lee.


Thanks, i think that'll do the trick if i manage to get it to work in assembly :)

Thanks again for all your help!


Top
 Profile  
 
 Post subject:
PostPosted: Sat Jan 21, 2006 2:17 am 
Offline

Joined: Tue Nov 15, 2005 7:58 am
Posts: 129
Location: Oregon, USA
Velorien wrote:
Hi,

Quote:
Specifically, has "multiple precision arithmetic" been covered? Software division algorithms? Use of the condition code flags? Binary coded decimal? Indexing?


The answer is no. The assistent for the class "Computer Architectures" showed us the basics (move, add...) and said RTFM and that was it.

Sadly, TA's are well known for this sort of behaviour. :(
Velorien wrote:
I have no textbooks nor sample programs. I've searched Google but found nothing for M68k so i've checked x86 asm examples. I've found multiple precision addition examples and i've tried to convert it for M68k with no luck. Then i remembered that Motorola uses High Endian, reversed the order of the additions (originaly i added from ho bytes to low) and it worked.

OK, I consider that to be fairly impressive.
Velorien wrote:
I don't know about Freescale's web site, and i'll try and look into the EHBASIC code but this is kinda urgent so i tried to get a faster answer here.

...

This is some kind of (sick :P) experiment at the colledge i'm attending :)
Wouldn't be the first time... :roll:


For Freescale (that used to be Motorola Semiconductors), you might start at:
http://www.freescale.com/webapp/sps/site/overview.jsp?nodeId=0162468rH3YTLC6951

For Google, try this search term:
M68K OR M68000 OR 68000 OR 68K "multiple precision"
with variations for your choice of topic (in the quotes) and language.
I found several promising links, but nothing quickly & easily accessible. :(

I see Lee has covered the specifics pretty well, so I'll leave it at that unless you ask for more help.


Top
 Profile  
 
 Post subject:
PostPosted: Sat Jan 21, 2006 5:45 pm 
Offline

Joined: Wed Jan 18, 2006 10:07 pm
Posts: 11
Just reporting in... i'm doing the victory dance right now because i've managed to implement Lee's solution and... it works!! :)

Thank you guys you're the best!!!1 :)

Thanks for everything!


Top
 Profile  
 
 Post subject:
PostPosted: Fri Feb 03, 2006 5:10 pm 
Offline

Joined: Mon Jan 16, 2006 3:04 pm
Posts: 7
people i have a problem now :)
that 48 bit number i have to print out on the screen. this algorithm taht lee gave doesn't work for larger numbers :(

the thing is if i have FFFF FFFF in one register, the DIVU does nothing because it can't put the result and remainder into 16 bits each :(

it only works for smaller number like 500 x 500 x 500 (decimal) or so....
and the assignment is to multiply three 16 bit numbers, so that means it should give the correct result for numbers up to 65535 x 65535 x 65535
right?

:(

please help me


Top
 Profile  
 
 Post subject:
PostPosted: Fri Feb 03, 2006 7:10 pm 
Offline

Joined: Mon Jan 16, 2006 3:04 pm
Posts: 7
ok, no need, i solved it
just had to upgrade lee's algorithm a bit :)

Code:
         |       64 bit very long word       |
                  |                 |
                  V                 V
         | 32 bit longword | 32 bit longword |
             |        |        |        |
             V        V        V        V
         | word A | word B | word C | word D |   word A always $0000
        |         |        |        | 
        V        V          |   |
      D3 | word A | word B |   |   |
        |   10 |   |   |
    -------------------   |   |
    | remain | result |   |   |
swap                |   |
    |result h| remain |   |   |
                      |        |        |
                      V        V        |
               D6 | word B | word C |   |
divide by                  |     10 |   |
                  -------------------   |
                  | remain | result |   |
swap words                              |
                  |result h| remain |   |
                      |        |        |
                      |        V        V
                      | D7 | remain | word D |
divide by             |             |     10 |
                      |    -------------------
                      |    | remain |result l|
swap words            |
                      |    |result l| remain | -> remainder is digit
                      |        |
                      V        V
         | $0000  |result h|result l| D5
             |        |        |
             V        V        V
| word A | word B | word C | word D |   for next divide



Top
 Profile  
 
 Post subject:
PostPosted: Fri Feb 03, 2006 7:28 pm 
Offline

Joined: Mon Dec 27, 2004 11:40 pm
Posts: 318
AvEnGeR wrote:
that 48 bit number i have to print out on the screen. this algorithm taht lee gave doesn't work for larger numbers :(

Yes it does, you just need to start with the highest longword, which will never be bigger than $0000FFFD, and work your way down from there.

Lee.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 21 posts ]  Go to page 1, 2  Next

All times are UTC


Who is online

Users browsing this forum: No registered users and 8 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron
Powered by phpBB® Forum Software © phpBB Group