Conditional structures: Difference between revisions
Content added Content deleted
Puppydrum64 (talk | contribs) |
Puppydrum64 (talk | contribs) (→{{header|68000 Assembly}}: clarification and better examples.) |
||
Line 220: | Line 220: | ||
RTS ;this "RTS" acts as a JMP to the address we just put on the stack.</lang> |
RTS ;this "RTS" acts as a JMP to the address we just put on the stack.</lang> |
||
=={{header|68000 Assembly}}== |
=={{header|68000 Assembly}}== |
||
Like [[6502 Assembly]], 68000 Assembly has several different condition states the CPU can use to branch. As is typical with assembly languages, branching code is less straightforward than on high-level languages. There is no "if" statement per se; the correct branch to use depends more so on the expression being evaluated. |
Like [[6502 Assembly]], 68000 Assembly has several different condition states the CPU can use to branch. As is typical with assembly languages, branching code is less straightforward than on high-level languages. There is no "if" statement per se; the correct branch to use depends more so on the expression being evaluated. |
||
In assembly, if a branch statement doesn't result in a branch taken, execution moves to whatever instruction is underneath the branch. If a branch is taken, execution jumps to the label specified by the branch instruction. A chart below will explain the different ways branches can occur. In addition to those, there are unconditional branches <code>BRA</code> and <code>JMP</code> which are the equivalent of <code>GOTO</code> in [[BASIC]] and [[C]]. |
|||
===CMP=== |
===CMP=== |
||
The most commonly used comparator is <code>CMP</code>. It can operate at byte, word, or long length. Anything outside of the " |
The most commonly used comparator is <code>CMP</code>. It can operate at byte, word, or long length. Anything outside of the "range" of its size parameter is ignored. |
||
<lang 68000devpac>MOVE.L #$FFFFFF00,D0 |
<lang 68000devpac>MOVE.L #$FFFFFF00,D0 |
||
CMP.B #0,D0 ;equals zero, so zero flag is set. |
CMP.B #0,D0 ;equals zero, so zero flag is set. |
||
CMP.W #0,D0 ;doesn't equals zero, so zero flag is clear.</lang> |
CMP.W #0,D0 ;doesn't equals zero, so zero flag is clear.</lang> |
||
Other than its |
Other than its size parameter, <code>CMP</code> works very similar to [[6502 Assembly]]. It returns both a test for equality and a size comparison (i.e. which number is greater than the other.) This chart from [http://www.easy68k.com/paulrsm/doc/trick68k.htm 68000 Tricks and Traps] sums it up nicely. If you use <code>CMP D0,D1</code> at any data size, this is what you get: |
||
<pre> |
<pre> |
||
Relationship Signed Unsigned |
Relationship Signed Unsigned |
||
Line 250: | Line 252: | ||
In addition to bit testing, <code>TST</code> will set the processor flags as if the value in a register or memory was just loaded there, even if it had been there for a while. This does not change the value in any register or memory; it just updates the flags, so it is very handy for introspection into the CPU's internal memory without altering it in any way. |
In addition to bit testing, <code>TST</code> will set the processor flags as if the value in a register or memory was just loaded there, even if it had been there for a while. This does not change the value in any register or memory; it just updates the flags, so it is very handy for introspection into the CPU's internal memory without altering it in any way. |
||
===If/Then/Else=== |
|||
These concepts can be emulated in assembly but it's a bit tricky for beginners to understand. The branch condition isn't always what you would expect. Sometimes it is reversed depending on what is easier to check. This is a common way to have an <code>IF condition==true THEN do something ELSE do nothing</code> style of statement. The code checks if <code>D0 == 3</code> and if it does, adds 7. If <code>D0 != 3</code>, execution just continues as normal. |
|||
<lang 68000devpac>CMP.L #3,D0 ;this works with any size operands, not just L. |
|||
BNE doNothing |
|||
ADD.L #7,D0 |
|||
doNothing: |
|||
;rest of program</lang> |
|||
Rather than branch to a different section of code if <code>D0 == 3</code>, the program branched if it <b>DIDN'T</b> equal 3, skipping the add 7. |
|||
===Switch=== |
===Switch=== |
||
Switch and cases are easy to implement with a return spoof. If the cases are not a consecutive numeric sequence like in the example below, you can use a lookup table to match the selector variable's values with an index into the table of case routine addresses. |
Switch and cases are easy to implement with a return spoof. If the cases are not a consecutive numeric sequence like in the example below, you can use a lookup table to match the selector variable's values with an index into the table of case routine addresses. |