Assembly Program (digit conversion)

Discussion in 'Programmer's Corner' started by frogacult, May 9, 2008.

Apr 30, 2008
27
0
helo,
I am programming on MOTOROLA 68000
The program i have to make will check if the digits d2,d4,d6 of the bytenum stored in memory \$400400 are "1". If all the digits (d2,d4,d6) are "1" the program will set "1" the 4 most signifficant bytes of memory point \$400401. Else (the digits are'nt "1") it will set "1" the 4 less significant bytes of the memory point \$400401.
The exercise aks to run the program 3 times each time for different number
stored in memory \$400400 :

a)C2
b)65
c)D4

The way to read the status of the digit is to write " BTST 2,D0 ". This will read the digit d2 in the register D0. if d2 is "1" then the Z flag becomes "0".
if d2 is "0" then the Z flag becomes "1".
I've attached the code i wrote.I think it works for these numbers but the exercise has 2 restrictions

Not use over 5 Assembler Directives (DC.B, ORG, END, DS.B)
Not use over 7 Commands
Any idea, to program with another way?
Can i read the status ("0" or "1") of each digit inside a loop?

Mike

• code.txt
File size:
516 bytes
Views:
21
Last edited: May 10, 2008
2. Mark44 Well-Known Member

Nov 26, 2007
626
1
Hi Mike,
The way you were doing it looks good, except that you are using more instructions than your instructor specified. Since you're testing the 2nd, 4th, and 6th bits with one BTST instruction for each, what you need is something that will do all three at once.

You can use #\$54 (0101 0100) as a bit mask--it has bits 2, 4, and 6 set, and the other bits cleared. If you AND a number with this bitmask, it turns off bits 0, 1, 3, 5, and 7. After you get those bits turned off, you can tell pretty easily whether bits 2, 4, and 6 are on.

1. Set memory location \$400401 to \$0F (lower four bits set, upper four bits cleared).
2. Copy the number you want to check into a data register.
3. Turn off bits 0, 1, 3, 5, and 7. (AND the number in the register with the bitmask \$54.)
4. Subtract \$54 from D0.
5. If the result is not zero, you're done; otherwise, set memory location \$400401 to \$F0 (upper four bits set, lower four bits cleared).

Step 1 assumes that the number we're looking at doesn't have the right bits set. If we find a number with bits 2, 4, and 6 set, we'll change the value in this location later.
Step 2 copies the number we're investigating into a register.
When step 3 turns off bits 0, 1, 3, 5, and 7, it leaves bits 2, 4, and 6 however they were. If all three of these bits are on, the number is \$54. The subtraction in the next step will leave zero.

On the other hand, if one or more of bits 2, 4, and 6 are 0, then subtracting \$54 from this number leaves us with something that isn't zero.

Hopefully I've given you enough to go on without actually writing the code for you.
Mark

Apr 30, 2008
27
0
This is very cool, i didn't thought it!
This way is much better and easier

I want to ask something more, if i want to take ΤΗΕ "supplement by 2"
i can program with this way also?
Because i tried to program with commands BTST, BSET( sets 1 the digit),BCLR (sets 0 the digit) and the program gone too big and i'm not sure if it works good!!

The program checks first the digit d6 and then the digit d5 of a byte stored in memory \$400400.If d6 is "0" it will set the digits d2,d0 stored in memory \$400401 to "0".Else it will set the digits d2,d0 to "1".
If the digit d5 is "1" it will set the digit d3 to "0". Else it will make the "supplement by 2" of the 4 less significant bytes of the byte memory \$400401.
In memory \$400401 is stored the RESULT=\$C1 and in memory \$400400 are stored:
1)3F
2)45

I've attached the code i wrote below but it think i works with a bit-mask like u said before,does it ?

File size:
1.2 KB
Views:
16
4. Mark44 Well-Known Member

Nov 26, 2007
626
1

To take the two's complement of a byte, negate it using NEG.B. There are similar instructions for words or longwords.

I don't understand how this is connected to what you were asking about two's complement. These sound like separate problems to me, so please let me know if they aren't. In the meantime I'll think about what you're trying to do and see what I can come up with.

Last edited: May 11, 2008
5. Mark44 Well-Known Member

Nov 26, 2007
626
1
Here's the logic as I understand things. S in my pseudocode stands for source, which is the byte at location \$400400. D stands for destination, which is the byte at location \$400401. S.d6 represents bit 6 in the source byte. Similarly, D.d0 represents bit 0 in the destination byte.

(1) if (S.d6 == 0) set D.d2 and D.d0 to 0
else set D.d2 and D.d0 to 1

(2) if (S.d5 == 1), set D.d3 to 0
else replace D.d0, D.d1, D.d2, and D.d3 with the two's complement of this 4-bit value.

For the first part (1), BTST is reasonable to use to see if a bit in the source byte is set. BSET would be reasonable to use, but you have to use it once for each bit you want to set in the destination byte. You can set bits in the destination byte with fewer instructions, though, if you set or clear the bits all at once. For example, to clear D.d2 and D.d0 (i.e., set both to 0), AND the destination byte with \$FC (= %11111100). To set D.d2 and D.d0 (i.e., set both to 1), OR the destination byte with \$3 (=%00000011).

For the second part (2), you can use BCLR to clear D.d3 when S.d5 == 1. When S.d5 == 0, this is what I would do:

1. Store the destination byte in a register.
2. NEG the value in the register.
3. AND the value in the register with \$0F (to zero out the high 4 bits).
4. Copy the value in the register to the destination address.

To walk you through these steps, suppose that the destination byte is 3, or %00000011. Step 2 changes this to %11111101. Step 3 changes this to %00001101.

Hope this helps.
Mark