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:
| Instruction | Computes | To |
|---|---|---|
CMP.t src,Dk | Dk − src, without storing the result | compare Dk with src |
CMPI.t #n,dst | dst − n | compare with a constant, in memory or in a register |
TST.t dst | dst − 0 | find 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 if | Signed | Unsigned |
|---|---|---|
dst = src | BEQ | BEQ |
dst ≠ src | BNE | BNE |
dst > src | BGT | BHI |
dst ≥ src | BGE | BHS (or BCC) |
dst < src | BLT | BLO (or BCS) |
dst ≤ src | BLE | BLS |
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