Version without JavaScript, read-only: workshops, quizzes and running code are not available here. Full version · Catalogue · Sign in

Lecture notes · chapter 4

Tests, jumps and loops

Comparing, jumping according to the flags, and translating the if, while and for statements of a high-level language into assembly.

Jumping

The unconditional jump

BRA ETIQ (branch always) writes the address of ETIQ into PC: execution carries on there. It is the goto of high-level languages, and it is the only way to go back and make a loop.

Comparing

A conditional branch tests nothing by itself: it reads the flags left by the previous instruction. They are set with:

InstructionComputesTo
CMP.t src,DkDk − src, without storing the resultcompare Dk with src
CMPI.t #n,dstdst − ncompare with a constant, in memory or in a register
TST.t dstdst − 0find out whether dst is zero, negative or positive

Many instructions already set the flags: after MOVE.W X,D0, you know whether X is zero or negative without a TST.

Conditional branches

After CMP src,dst, the branch Bcc ETIQ jumps to ETIQ if the condition is true, and carries on with the next line otherwise.

Jumps ifSignedUnsigned
dst = srcBEQBEQ
dst ≠ srcBNEBNE
dst > srcBGTBHI
dst ≥ srcBGEBHS (or BCC)
dst < srcBLTBLO (or BCS)
dst ≤ srcBLEBLS

And, after any instruction: BMI if the result is negative (N = 1), BPL if it is positive or zero, BVS if there was an overflow.

Translating control structures

The rule of every translation: jump when the condition is false, to skip over the block it guards.

If… else

* if (X = 0) then Y <- 1 else Y <- 2
        TST.W   X
        BNE     SINON       ; condition false: go to the else part
        MOVE.W  #1,Y        ; then
        BRA     FINSI       ; do not execute the else part
SINON   MOVE.W  #2,Y        ; else
FINSI

Without the BRA FINSI, the program would also execute the “else” block after the “then” block.

While

* while (D0 < 100) do D0 <- 2 * D0
TANTQUE CMP.W   #100,D0     ; D0 - 100
        BGE     FINTQ       ; condition false (D0 >= 100): leave
        ADD.W   D0,D0       ; loop body
        BRA     TANTQUE     ; back to the test
FINTQ

For, with DBRA

The 68000 has an instruction made for counted loops: DBRA Dk,ETIQ subtracts 1 from the low word of Dk, then jumps to ETIQ if Dk.W is not −1. To repeat a body $n$ times, initialise the counter to $n - 1$.

* sum of the N words of the array TAB
N       EQU     10
        LEA     TAB,A0
        CLR.W   D0          ; sum
        MOVE.W  #N-1,D1     ; N iterations: counter from N-1 down to 0
BCL     ADD.W   (A0)+,D0
        DBRA    D1,BCL
        MOVE.W  D0,SOMME

A loop over a string

A string ends with a null byte. Its length is computed by moving forward until that zero:

* D0 <- length of the string pointed to by A0
        MOVEQ   #0,D0
BCL     TST.B   (A0)+       ; null byte? (A0 advances by 1)
        BEQ     FIN
        ADDQ.L  #1,D0
        BRA     BCL
FIN

We do not know the number of iterations in advance: it is a “while”, not a “for”, hence BRA rather than DBRA.

Try it

The same computation, as a complete program, which prints the length with service 3 of TRAP #15. Change the string, run, and check the length printed; then follow it step by step, watching A0 advance by one byte at each iteration.

        ORG     $1000
START   LEA     CH,A0           ; A0 points to the string
        MOVEQ   #0,D1           ; length
BCL     TST.B   (A0)+           ; null byte? (A0 advances by 1)
        BEQ     FIN
        ADDQ.L  #1,D1
        BRA     BCL
FIN     MOVE.B  #3,D0           ; service 3: print D1.L
        TRAP    #15
        SIMHALT

CH      DC.B    'Bonjour',0
        END     START