FUNCTION |
Controls a loop of instructions. The parameters are: a
condition code, a data register (counter), and an offset value.
The instruction first tests the condition (for termination); if it
is true, no operation is performed. If the termination condition is
not true, the low-order 16 bits of the counter are decremented by
one. If the result is -1, execution continues at the next
instruction, otherwise, execution continues at the specified
address.
Condition code 'cc' specifies one of the following:
0000 | F | False | Z = 1 |
0001 | T | True | Z = 0 |
0010 | HI | HIgh | C + Z = 0 |
0011 | LS | Low or Same | C + Z = 1 |
0100 | CC | Carry Clear | C = 0 |
0101 | CS | Carry Set | C = 1 |
0110 | NE | Not Equal | Z = 0 |
0111 | EQ | EQual | Z = 1 |
|
1000 | VC | oVerflow Clear | V = 0 |
1001 | VS | oVerflow Set | V = 1 |
1010 | PL | PLus | N = 0 |
1011 | MI | MInus | N = 1 |
1100 | GE | Greater or Equal | N (+) V = 0 |
1101 | LT | Less Than | N (+) V = 1 |
1110 | GT | Greater Than | Z + (N (+) V) = 0 |
1111 | LE | Less or Equal | Z + (N (+) V) = 1 |
|
Keep the following in mind when using DBcc instructions:
- A DBcc acts as the UNTIL loop contruct in high level
languages. E.g., DBMI would be "decrement and branch until
minus".
- Most assemblers accept DBRA or DBF for use when no condition
is required for termination of a loop.
The DBcc will, unlike the Bcc instruction, take the branch only if
the set of conditions are NOT satified. The loop will be terminated
if the condition is true, or the counter is zero BEFORE a decrement,
and wrap to -1. This mean that if you execute code like:
| move.w | #30,d0 |
| | |
.Loop | | |
| move.l | (a0)+,(a1)+ |
| dbf | d0,.Loop |
| | |
|
then the copy will be executed *31* times, and 124 bytes of memory will be copied, not 120.
|
| | |
| A good practice is therefore to write: |
| | |
| move.w | #31-1,d0 |
| | |
.Loop | | |
| move.l | (a0)+,(a1)+ |
| dbf | d0,.Loop |
| | |
|
To compare two strings that may be in excess of 64k length for
beeing equal, you could execute the following code:
|
| ... |
| | |
| move.l | #$53452-1,d0 |
| beq.s | .NoLength ; Zero length! |
| bra.s | .StartOuterLoop; The upper word contain count of 65536's... |
| | |
.OuterLoop | | |
| swap | d0 |
| | |
.InnerLoop | | |
| cmp.b(a0)+,(a1)+ |
| dbned0,.InnerLoop; Remember, drop trough on condition TRUE. |
| | |
.StartOuterLoop | | ; d0 will be $FFFF on 2.+ run-through
| bne.s | .NotEqual; Dropped through due to Not Equal? |
| swap | d0; Get upper part of word... |
| dbf | d0,.OuterLoop |
| ... |
| | |
|
It would not be possible to use two sets of DBNEs, as SWAP
changes the condition codes - and we don't want the drop-
though to be on account of D0, instead of the compares...
|
| | |
|
Another neat trick is to use instruction as a conditional
decrementer; this code will decrement d0.w if the last
instruction returned NOT EQUAL:
|
| ... |
| dbeq | d0,.Next |
| | |
.Next | | |
| ... |
|