• Keine Ergebnisse gefunden

GENERAL PROGRAMMING METHODS 29

Im Dokument Assembly Language Subroutines (Seite 42-45)

Branching Based on Magnitude Comparisons

CHAPTER 1. GENERAL PROGRAMMING METHODS 29

The result does not have the sign that we want, but the Parity/Overflow flag indicates that two's complement overflow has changed the real sign.

We have to look for both a true positive (the sign we want, unaffected by overflow) or a false negative (the opposite of the sign we want, but inverted by two's complement overflow).

Examples

1. Branch to DEST if the accumulator contains a signed number greater than or equal to the number VALUE.

FNEG;

;PERFORM THE COMPARISON

;DID OVERFLOW OCCUR?

;NO. BRANCH IF RESULT POSITIVE

;YES. BRANCH IF RESULT NEGATIVE There are no relative jumps based on the Parity/Overflow flag.

2. Branch to DEST if the accumulator contains a signed number less than the contents of memory address ADDR.

FPOS:

;PERFORM THE COMPARISON

;DID OVERFLOW OCCUR?

;NO. BRANCH IF RESULT NEGATIVE

;YES. BRANCH IF RESULT POSITIVE

Remember, lP PE means "jump on overflow," while lP PO means "jump on no overflow."

The programmer should also note that this is one of the few cases in which the Z80 is not fully upward-compatible with the 8080 microprocessor.9 The 8080 has no overflow indicator and the P flag always indicates even parity.

There are some cases in which overflow cannot occur and all we must do is use the Sign flag instead of the Carry flag for branching. These cases are the following:

. The two numbers have the same sign. When this occurs, the difference is smaller in magnitude than the larger of the two numbers and overflow cannot occur. You can easily determine if two numbers have the same sign by EXCLUSIVE ORing them together and checking the Sign flag. Remember, the EXCLUSIVE OR of two bits is 1 if and only if the two bits have different values.

XOR VALUE JP P.NOOVF

;COULD OVERFLOW OCCUR?

;NOT IF SIGNS ARE THE SAME

30

Z80 ASSEMBLV LANGUAGE SUBROUTINES

. A value is being compared with zero. In this case, the Sign flag must be set and examined.

Examples

1. Jump to DEST if the accumulator contains a signed positive number.

AND A ;SET FLAGS FROM VALUE IN A . .JP P, DEST

2. Jump to DEST if an 8-bit register contains a signed negative number.

INC reg DEC reg .JP M, DEST

;SET FLAGS FROM VALUE IN REGISTER

This sequence does not affect the accumulator or the register.

3. Jump to DEST if memory location ADDR contains a signed positive number.

LD HL,ADDR INC (HU

DEC (HU

. ..IP P, DEST

;POINT TO DATA IN MEMORY

;BRANCH IF DATA IS POSITIVE This sequence does not affect the accumulator or the memory location.

Tables 1-7 and 1-8 summarize the common instruction sequences for making decisions with the Z80 microprocessor. Table 1-7 lists the sequences that depend only on the value in the accumulator; Table 1-8 lists the sequences that depend on numerical comparisons between the value in the accumulator and a specific number, the contents of a register, or the contents of a memory location (addressed through HL or an index register). Table 1-9 contains the sequences that depend only on the contents of a memory location.

LOOPING

The simplest way to implement a loop (that is, to repeat a sequence of instructions) with the Z80 microprocessor is to perform the following steps:

I. Load register B with the number of times the sequence is to be repeated.

2. Execute the sequence.

3. Use the DJNZ instruction to decrement register B and return to Step 2 if the result is not O.

The DJNZ instruction is useful for loop control since it combines a decrement and a conditional relative branch. Note that DJNZ always operates on register Band

CHAPTER 1· GENERAL PROGRAMMING METHODS

31

Table 1·7. Decision Sequences Depending on the Accumulator Alone

Condition Flag Setting Instruction Conditional Jump

Any bit = 0 BIT n,A JR Z orJP Z

Any bit = I BIT n,A JR NZ orJP NZ

Bit 7 = 0 RLA, RLCA, or ADD A,A JR NC orJP NC

Bit 7= I RLA, RLCA, or ADD A,A JR C orJP C

Bit 6= 0 ADDA,A JP P

Bit 6= I ADDA,A JPM

Bit 0= 0 RRA or RRCA JR NC orJP NC

BitO= I RRA orRRCA JR CorJPC

Equals zero AND A orORA JR Z orJP Z

Not equal to zero ANDAorORA JR NZ orJP NZ

Positive (MSB = 0) ANDAorORA JP P

Negative (MSB = I) AND A or OR A JPM

Table 1·8. Decision Sequences Depending on Numerical Comparisons with the Accumulator (Using CP)

Condition Conditional Jump

Equal JR Z orJP Z

Not equal JR NZ orJP NZ

Greater than or equal (unsigned) JR NC orJP NC

Less than (unsigned) JR C or JP C

Greater than or equal (signed) JP P (assuming no overflow)

Less than (signed) JP M (assuming no overflow)

Note: All conditions assume that the accumulator contains the primary operand; for example, less than means "accumulator less than other operand."

Table 1·9. Decision Sequences Depending on a Memory Location Alone

Condition Flag Setting Instruction(s) Any bit = 0 BIT n, (HL) or (xy+OFFSET) Any bit = I BIT n,(HL) or (xy+OFFSET)

=0 INC,DEC

=1'0 INC, DEC

Conditional Jump JR Z orJP Z JR NZ orJP NZ JR Z orJP Z JR NZ orJP NZ

32

Z80 ASSEMBLY LANGUAGE SUBROUTINES

branches if B is not decremented to 0 - the instruction set does not provide any other combinations. However, DJNZ has limitations: It allows only an 8-bit counter and an 8-bit offset for the relative branch (the branch is thus limited to 129 bytes forward or 126 backward from the first byte of the instruction).

Typical programs look like the following:

LD B.NTIMES JNTIMES

=

NUMBER OF REPETITIONS LOOP:

Instructions to be rep~ated

DJNZ LOOP

We could, of course, use other 8-bit registers or count up rather than counting down.

These alternative approaches would require a slightly different initialization, an explicit DEC or INC instruction, and a conditional JR or JP instruction. In any case, the instructions to be repeated must not interfere with the counting of the repetitions.

Note that register B is special, and most programmers reserve it as a loop counter.

The 8-bit length of register B limits this simple loop to 256 repetitions. The programmer can provide larger numbers of repetitions by nesting single-register loops or by using a register pair as illustrated in the following examples:

. Nested loops LOOPO:

LOOPI:

LD LD C. NTIMM

B. NTIML JSTART OUTER COUNTER

;START INNER COUNTER Instructions to be repeated

DJNZ LOOPI DEC C

JR NZ,LOOPO

JDECREMENT INNER COUNTER JDECREMENT OUTER COUNTER

The outer loop restores the inner counter (register B) to its starting value (NTIML) after each decrement of the outer counter (register C). The nesting produces a mUltiplicative factor-the instructions starting at LOOPI are repeated NTIMM X NTIML times. We use register B as the inner counter to take maximum advantage of DJNZ. (Clearly, the inner loop is executed many more times than the outer loop.)

. A register pair as 16-bit counter LD BC, NTIMES

LOOP: ;INITIALIZE 16-BIT COUNTER

Instructions to be repeated DEC BC

LD A,B OR C JR NZ,LOOP

Im Dokument Assembly Language Subroutines (Seite 42-45)