MC 68000 MACHINE LANGUAGE COURSE PART IV by Mark van den Boer What a pity!! You missed the mega-surprise of part 3. Next time better luck! I am gonna take that holiday to Hawaii myself! This time I will discuss the Integer Arithmetic Instructions. The syntax used is of course the same as in part 3, so when in doubt refer to part 3. This class of instructions is used to do mathematical calculations. This group is very often used by assembly language programmers, especially the instructions for adding and subtracting. Integer Arithmetic Instructions Instruction: ADD Syntax: ADD Dn, ADD ,Dn Data sizes: byte, word, long Condition codes affected: X, C set by carry out of the most significant bit N set if the result was negative, cleared otherwise Z set if the result was zero, cleared otherwise V set if the result overflowed, cleared otherwise Addressing modes: Source: (destination is Dn) Dn An (An) (An)+ -(An) w(An) b(An,Rn) w l w(PC) b(PC,Rn) Destination: Dn (An) (An)+ -(An) w(An) b(An,Rn) w l Function: Add source to destination and put the result in destination. Examples: Instruction Before After ADD.W d0,d1 d0=00000011 d0=00000011 d1=0000FFFA d1=0000000B XNZVC=00000 XNZVC=11001 ADD.L (a0),d0 d0=00000022 d0=00000027 a0=12345678 a0=12345678 12345678 contains 5 XNZVC=00000 XNZVC=00000 Instruction: ADDA Syntax: ADDA ,An Data sizes: word, long Condition codes affected: None Addressing modes: Source: Dn An (An) (An)+ -(An) w(An) b(An,Rn) w l w(PC) b(PC,Rn) # Destination: An Function: Add a value to an address register. This operation does not change any of the condition code values. Note that most operations that have an address register as a destination does not change the condition codes. Example: Instruction Before After ADDA.L a0,a0 a0=00000002 a0=00000004 Notice that this instruction has the same effect as multiplying the address register with two (if this was possible). Instruction: ADDI Syntax: ADDI #, This instruction has exactly the same characteristics as the ADD instruction, except that the source can only be a constant. Instruction: ADDQ Syntax: ADDQ #, Same story as for ADDI, except that the immediate values in the source field can only range from 1 to 8. Q stands for Quick, since this instruction is the fastest way to add a number from 1 to 8 to a destination operand. A note on ADD, ADDI, ADDQ: Most assemblers accept the following instruction: ADD #1,Dn and will translate it automatically to ADDQ #1,Dn thus saving a few bytes of object code and some clock cycles execution time. Instruction: ADDX Syntax: ADDX Dn,Dn ADDX -(An),-(An) Data sizes: byte, word, long Condition codes affected: see ADD Function: Add X-bit and source to destination and store the result in destination. This instruction is used for multiple precision operations and is therefore only available with the two addressing modes mentioned. Example: Instruction Before After ADDX.B -(a0),-(a1) a0=10001001 a0=10001000 a1=10002001 a1=10002000 10001000 contains AA the same 10002000 contains 5A 10002000 contains 4 X=0 X=1 ADDX.B -(a0),-(a1) a0=10001000 a0=10000fff a1=10002000 a1-10001fff 10000fff contains 0 the same 10001fff contains 0 10001fff contains 1 X=1 X=0 In this example the word that begins at 10000fff is added to the word that begins at 10001fff. If one should try to do this with two ADD.W instruction an address error would occur since words always must be aligned to even addresses. This instruction can be compared to the ADC instruction of the 6502 and 6809. Instruction: CLR Syntax: CLR Data sizes: byte, word, long Condition codes affected: N always cleared Z always set V always cleared C always cleared Addressing modes: Dn (An) (An)+ -(An) w(An) b(An,Rn) w l Function: Set an effective address to zero. You will have noticed that you can't CLR an address register. However, most assemblers allow the programmer to CLR an address register by substituting CLR a0 with SUB.L a0,a0 . This instruction has exactly the same result. Example: Instruction Before After CLR.W d0 d0=ffffffff d0=00000000 NZVC=1011 NZVC=0100 Instruction: CMP Syntax: CMP ,Dn Data sizes: byte, word, long Condition codes affected: NZVC (X is not affected) Addressing modes (source): Dn An (An) (An)+ -(An) w(An) b(An,Rn) w l w(PC) b(PC,Rn) Function: compare an effective address with a data register. In fact all condition codes are set as if Dn- was performed. So CMP is kind of a subtraction which only affects the conditon codes. Example: Instruction Before After CMP.L d0,d1 d0=00000001 d0=00000001 d1=00000002 d1=00000002 NZVC=1111 NZVC=0000 Instruction: CMPA Syntax: CMPA ,An Data sizes: word, long Function: This instruction differs only from CMP in that the second operand is an address register and that byte isn't allowed as a data size. Instruction: CMPI Syntax: CMPI #,Dn Function: Yes, it is nearly exactly the same as compare but now the first operand must be a constant. Instruction: CMPM Syntax: CMPM (An)+,(An)+ Function: Again, nearly exactly the same as CMP, but now both the source and destination operand must be (An)+. This instruction is used to compare areas of memory. For those of you who have a working knowledge of C: strcmp can be programmed easy with this instruction. Note on all CMPx instructions. Most assemblers accept instructions like: CMP.W (a0)+,(a1)+ CMP.L #3,d0 Substitution of CMPM, CMPI and CMPA are automatically performed by the assembler. Instruction: DIVS Syntax: DIVS ,Dn Data sizes: word Condition codes affected: N behaves normal; undefined on overflow Z behaves normal; undefined on overflow V behaves normal C always cleared Addressing modes (source): Dn (An) (An)+ -(An) w(An) b(An,Rn) w l w(PC) b(PC,Rn) # Function: Guess what? This instruction performs a division between two signed numbers. The destination register is always a longword and the source operand is always a word. After the division the destination operand contains the result. The quotient is always in the lower word and the remainder is always in the high order word of the data register! This way a modulo operation is also performed, you just SWAP the data register and you have your result in the lower word of the data register. Overflow occurs when you attempt to divide a large number by a small number e.g. ffffff divided by 1, the result doesn't fit in a word. Another error occurs when attempting to divide by zero. In this case the 68000 generates an exception and will trap to a special routine which handles division by zero erros. On the Atari you must set up this routine yourself. E.g. FLOYD (a machine language monitor) responds to a division by zero with the following sentence "The answer is 42". Remember, don't panic when you see such an answer. Example: Instruction Before After DIVS #3,d0 d0=0000000B d0=00020003 NZVC=1111 NZVC=0000 Instruction: DIVU Function: Nearly exactly the same as DIVS, only this time both operands are assumed to be unsigned. Instruction: EXT Syntax: EXT Dn Data sizes: word, long Condition codes affected: N behaves normal Z behaves normal V always cleared C always cleared Function: turn a byte into a word, or turn a word into a long. This instruction provides a convenient way to turn a word into a long and still have the same value for that register. If the high order bit of the data register is 0, so the data register is positive, zeroes are padded in, otherwise ones are padded in. Example: Instruction Before After EXT.W d0 d0=000000ff d0=0000ffff EXT.L d0 d0=ffff0000 d0=00000000 Instruction: MULS Syntax: MULS ,Dn Data sizes: word Condition codes affected: N behaves normal Z behaves normal V always cleared C always cleared Addressing modes (source): Dn (An) (An)+ -(An) w(An) b(An,Rn) w l w(PC) b(PC,Rn) # Function: Ah! another very handy instruction. This instruction performs a multiplication of the source and destination operand, putting the result in the destination operand. Example: Instruction Before After MULS #3,d0 d0=0000000B d0=00000021 NZVC=1111 NZVC=0000 Instruction: MULU Function: Nearly exactly the same as MULUS, only this time both operands are assumed to be unsigned. Instruction: NEG Syntax: NEG Data sizes: byte, word, long Condition codes affected: XNZVC (all behave normal) Addressing modes: Dn (An) (An)+ -(An) w(An) b(An,Rn) w l Function: negate an effective address operand. In a high level language it would look like this: a = -a Example: Instruction Before After NEG.L d0 d0=00000001 d0=ffffffff Instruction: NEGX Syntax: NEGX Data sizes: byte, word, long Condition codes affected: XNZVC (all behave normal) Addressing modes: Dn (An) (An)+ -(An) w(An) b(An,Rn) w l Function: negate an effective address operand and add the X-bit to the result. This is another instruction which provides a way to handle multi-precision (e.g. 8-byte integers). Example: Instruction Before After NEGX.L d0 d0=00000001 d0=00000000 X=1 X=1 Instructions: SUB, SUBA, SUBI, SUBQ, SUBX All these instruction perform subtractions. They only differ in that way from from the ADD instructions, all other characteristics are the same. Instruction: TAS Syntax: TAS Data sizes: byte Condition codes affected: N evaluated before setting the byte Z evaluated before setting the byte V always cleared C always cleared Addressing modes: Dn (An) (An)+ -(An) w(An) b(An,Rn) w l Function: First test the operand and set the condition codes, then set the high-order bit to 1. People who know what semaphores (in programming of course...) are, immedia- tely will love this instruction. For those who don't know what semaphores are: M. Ben Ari has written a good book on the subject called "Principles of Concurrent Programming". Never, I repeat never, read a book on this subject written by a certain Ir. E.H.H. Dijkstra (not the famous Dijkstra, this Dijkstra will never be famous). Example: Instruction Before After TAS $436 $436=00 $436=80 NZVC=1111 NZVC=0100 TAS $436 $436=FF $436=FF NZVC=1111 NZVC=1000 Instruction: TST Syntax: TST Data sizes: byte, word, long Condition codes affected: N behaves normal Z behaves normal V always cleared C always cleared Addressing modes: Dn (An) (An)+ -(An) w(An) b(An,Rn) w l Function: test an effective address operand. This instruction can be seen as CMP ,d0 where d0 is 0. TST is nearly always followed by a branch instruction (more on these later) To the people who also read the last lines (I hope you've also read most of the preceeding ones): Phone me and tell me how you like this course. My phonenumber (in Holland) is: 013-422397 Originally published in ST NEWS Volume 2 Issue 3.