0

So I am using a very strange CPU. It does not use bitwise operators and instead uses addition, subtraction, multiplication, division and modulo. It is 8 Bit and uses 5 registers, the accumulator and the X, Y, Z and PC registers. Here is the instruction set:

0 - BRK - Break (end) the program
1 - ADD - Add the operand (the byte following the instruction) to the accumulators value.
2 - SUB - Subtract the operand from the accumulators value.
3 - MUL - Multiply the operand by the accumulators value and store that in the accumulator
4 - DIV - Divide the operand by the accumulators value and store that in the accumulator
5 - MOD - Modulo (the remainder of division) the operand by the accumulators value and store that in the accumulator
6 - PAU - Pause for the amount of seconds specified by the operand
7 - LDA# - Load the accumulator with the operand's value
8 - LDA$ - Load the accumulator with the memory address value corresponding to the operand's value.
9 - LDX# - Load the X register with the operand's value
10 - LDX$ - Load the X register with the memory address value corresponding to the operand's value.
11 - LDY# - Load the Y register with the operand's value
12 - LDY$ - Load the Y register with the memory address value corresponding to the operand's value.
13 - LDZ# - Load the Z register with the operand's value
14 - LDZ$ - Load the Z register with the memory address value corresponding to the operand's value.
15 - STA - Store the accumulator into the address specified by the operand
16 - STX - Store the X register into the address specified by the operand
17 - STY - Store the Y register into the address specified by the operand
18 - STZ - Store the Z register into the address specified by the operand
19 - INA - Increment the accumulator
20 - INX - Increment the X register
21 - INY - Increment the Y register
22 - INZ - Increment the Z register
23 - TAX - Transfer the content of the accumulator to the X register
24 - TAY - Transfer the content of the accumulator to the Y register
25 - TAZ - Transfer the content of the accumulator to the Z register
26 - TXA - Transfer the content of the X register to the accumulator
27 - TXY - Transfer the content of the X register to the Y register
28 - TXZ - Transfer the content of the X register to the Z register
29 - TYA - Transfer the content of the Y register to the accumulator
30 - TYX - Transfer the content of the Y register to the X register
31 - TYZ - Transfer the content of the Y register to the Z register
32 - TZA - Transfer the content of the Z register to the accumulator
33 - TZX - Transfer the content of the Z register to the X register
34 - TZY - Transfer the content of the Z register to the Y register
35 - JMP - Jump to the memory address specified by the operand and start executing code from there
36 - JAZ - Jump to the memory address specified by the operand and start executing code from there, only if the accumulator is equal to 0
37 - RND - Generate a random number from 0 to the value in the operand and store that in the accumulator
38 - INP - Get input from the user and store that in the accumulator
39 - OUT - Display the accumulator in the output box
40 - CLO - Clear the output box
41 - JNZ - Jump to the memory address specified by the operand and start executing code from there, only if the accumulator is not equal to 0
42 - NOP - Do nothing
43 - CMP - If the operand equals the value in the accumulator, set the accumulator to 0
44 - CPX - If the operand equals the value in the X register, set the accumulator to 0
45 - CPY - If the operand equals the value in the Y register, set the accumulator to 0
46 - CPZ - If the operand equals the value in the Z register, set the accumulator to 0
47 - INC - Increment the value in the memory address specified by the operand and store that in that memory address
48 - DEC - Increment the value in the memory address specified by the operand and store that in that memory address
49 - DEA - Decrement the accumulator
50 - DEX - Decrement the X register
51 - DEY - Decrement the Y register
52 - DEZ - Decrement the Z register

So using these instructions, how would you compare one number to another to see if it is greater or less.

  • A slow naive implementation could subtract 1 in a loop from both operands and see which one gets to zero first. – Jester Jun 22 '20 at 20:03
  • How would I time that? – justAnotherCoder Jun 22 '20 at 20:11
  • Huh? `if (x - y == 0) equal() else repeat { if (x == 0) x_less(); if (y == 0) y_less(); x--; y--; }` This is for unsigned arithmetic. – Jester Jun 22 '20 at 20:14
  • 2
    Though Im not sure if this works for signed values, you could try just using the `DIV` operation: `x / y` using integer division will be 0 if `y > x` and some value greater than 0 if `y <= x`. Something like `TYA ; DIV X ; JAZ y_greater ; JMP x_greater_or_equal` – Unn Jun 22 '20 at 20:25
  • [Calculate absolute difference |A-B| in assembly using only INC, DEC, JNZ, HALT - interview question](https://stackoverflow.com/q/62118756) has a similar restriction, getting absolute difference with only a compare against zero being available, no shifts. But that didn't have division, a much more powerful operation. – Peter Cordes Jun 22 '20 at 21:14
  • @Unn: The OP might actually want unsigned greater / less (what some ISAs call above / below), in which case DIV is a great idea. Otherwise you could use DIV and MOD as right shift / bit-extract to break down values into a base 2 representation (one byte per digit aka bit) and manually implement 2's complement comparison. Or with unsigned MOD, just separate the top bit from the other 7, and treat it as a sign bit. – Peter Cordes Jun 22 '20 at 21:20

0 Answers0