HenryCase wrote:
The CPU has the ability to recognise an XOR opcode, and every other opcode it uses, and if part of an instruction isn't an opcode it is data. Therefore a CPU knows, after the 'decode' process, what is an opcode and what is an operand, correct? This requires just a yes or no answer.
No. Here's an example to make this very straightforward. Assume a mythical computer with an instruction set containing ADD, LOAD, and STORE. ADD sums two registers and puts its output in the first register. We assign these instructions numbers, 0 through 3. Our computer has only two registers, which we'll number 0 and 1. Our computer uses 4 bit 'bytes' (to keep the math simple for me) so we have possible values in each 'byte' of 0 through 15, or 0xF. Now, let's say I have 20 'bytes' of memory starting at 0x00. OK? This is actually a fairly reasonable computer to use as an example here. It's missing branching and comparisons, but they will fit within the model, but they're not needed for this example.
Suppose I want to write a program to add three numbers (3, 5, and 2) without carry, it might look something like this, assuming the three numbers are in the first 3 'bytes' of memory already and I want to output to fourth 'byte':
LOAD reg0, 0x0
LOAD reg1, 0x1
ADD
LOAD reg1, 0x2
ADD
STORE reg1, 0x3
now this assembles to:
0x10011101120313
that's our actual binary executable for our mythical computer there.
Now, suppose I write a program (for a version of this computer with more memory and some I/O capability) which stores a user password. This will be done by using two four-bit 'bytes' per character, so we'll use ASCII. Only we're going to use ROT-n to encode the passwords so they can't be as easily read. Arbitrarily, the program has selected -21 for the offset, n, so each letter has 21 subtracted from it's ASCII value before storage. So if the user enters password "#l|l}n~" we get 0x10011101120313 as the encoded password.
Yes, that's the same binary code as the program. So which is which? Which one will the program execute? Both, and with identical results either way.
Real software will unfortunately have runs of bytes where there is a mix of program code and data. So you can't tell what's code, what's data, and what might be a special kind of data called a pointer.
The _only_ way to implement memory protection for a system where programs read and write shared memory is to run each program in a virtual machine where it is the only application running, like Apple did with the Classic environment in OS X, or to write each and every program that will run on the system to inform the operating system of its intention to use shared memory. Amiga software wasn't written that way, so that options doesn't work.