CPU design help.

n72.75

Move slow and try not to break too much.
Orbiter Contributor
Addon Developer
Tutorial Publisher
Donator
Joined
Mar 21, 2008
Messages
2,699
Reaction score
1,360
Points
128
Location
Saco, ME
Website
mwhume.space
Preferred Pronouns
he/him
I have a question about CPU instructions.

Say I have the following

mov [0x0010], ax

versus

mov [0x0010], [0x0011]

How does the CPU know the difference between a register and a memory address?
 

tl8

Addon Developer
Addon Developer
Tutorial Publisher
Joined
Oct 16, 2007
Messages
3,645
Reaction score
25
Points
88
Location
Gold Coast QLD
I have a question about CPU instructions.

Say I have the following

mov [0x0010], ax

versus

mov [0x0010], [0x0011]

How does the CPU know the difference between a register and a memory address?

That is a function of the assembler.

Each different move operation type actually has a different op code and the one chosen is done by the assembler.
 

dbeachy1

O-F Administrator
Administrator
Orbiter Contributor
Addon Developer
Donator
Beta Tester
Joined
Jan 14, 2008
Messages
9,218
Reaction score
1,566
Points
203
Location
VA
Website
alteaaerospace.com
Preferred Pronouns
he/him
tl8 is correct. In addition, be advised that with x86 processors you cannot move memory to memory in a single instruction. For example:

Code:
mov eax, [0123456h]     ; OK (selector DS assumed).  
mov dword ptr ds:[01234567h], eax  ; OK.  Machine language Opcodes are: [COLOR="Red"]3E A3[/COLOR], followed by bytes 67 45 23 01  [the 67 45 23 01 bytes are the memory address]
[COLOR="Red"]mov dword ptr ds:[0123456h], ds:[01234567h]   ; ERROR: improper operand type[/COLOR]

To copy memory from one location to another you must go through a register as per the first two asm lines above. For more information, see here.
 

Urwumpe

Not funny anymore
Addon Developer
Donator
Joined
Feb 6, 2008
Messages
37,653
Reaction score
2,375
Points
203
Location
Wolfsburg
Preferred Pronouns
Sire
There are also some kinds of CPU, which have memory mapped registers, there is no difference between a register address and a memory address.

Generally, you have a special mnemonic for different operand types to each mnemonic equates one operation code in the CPU. But many assemblers also do that job for you by understanding which operands you have and generate the fitting operation codes for you.

The AP/101S assembler for example, which is IBM High-Level Assembler (HLA), does not know special register symbols. You give it a number and this number can be a macro which you named by the register that you mean. For telling the assembler that this number is a register, you need to use the right mnemonic for the operands.
 

orb

New member
News Reporter
Joined
Oct 30, 2009
Messages
14,020
Reaction score
4
Points
0
How does the CPU know the difference between a register and a memory address?
If it's x86, then from ModR/M byte of the instruction, which selects operands, and from the "direction" bit in the opcode, which chooses which of them is source and which destination (and additionally from "width" / "size" bit of opcode, which selects the width of the operands, and SIB byte if there is [scale*index+base] used).

For x86:
 

toddhisattva

New member
Joined
Apr 28, 2008
Messages
20
Reaction score
0
Points
1
Addressing Addressing Modes

How does the CPU know the difference between a register and a memory address?

These are different *addressing modes* (that's what you should gogulate upon). In sane instruction sets, these modes map into bits in the instructions. As someone already said, it's the assembler's job to figure out what you mean and pick the right instruction and set its addressing mode bits and transcribe your operands into the instruction stream.

Let's say any instruction starting with 0001 means "move." The next nybble might specify the addressing mode. In a register-to-register mode, the next two nybbles might be the registers. Boom, it's there in a 16-bit instruction no need to fetch operands.

Register-to-memory modes will fetch an operand for the address. And so on.

This got quite ridiculous after a while, with some architectures having 18 modes, so you'd have stuff like a base address register to which was added the result of multiplying another register by an operand, plus another offset operand. All in one instruction.

It turned out that using the complicated modes was often *slower* than explicitly calculating the address with individual discrete instructions. Thus the RISC revolution. ISAs went from 25 addressing modes to six, or four. (Isn't that a song?)

Now, I mentioned "sane" above. x86 is insane. I am long past caring exactly how it does what it does. It is not "orthogonal" and some registers have special purposes and they're intimately related to addressing modes - segment registers, a sort of dedicated base address register. (This actually does get kind of cool with x86's execution level "rings" but was just a pain before the 80386.)

But these days - and if I'm wrong somebody correct me - on the inside x86 chips crack their complicated instructions into streams of simpler ops, which are executed by a kind of VLIW (Very Long Instruction Word, means lots of room to specify x86 weirdness) engine. The crazy addressing modes are thus simplified, and coded nicely into slots in the VLIW machine's words. Maybe I'm thinking of the Athlon and Intel does it different.

Whatever. The trend is toward fewer addressing modes and doing address calculation explicitly in honest code. Fewer modes but more registers.
 

Urwumpe

Not funny anymore
Addon Developer
Donator
Joined
Feb 6, 2008
Messages
37,653
Reaction score
2,375
Points
203
Location
Wolfsburg
Preferred Pronouns
Sire
This got quite ridiculous after a while, with some architectures having 18 modes, so you'd have stuff like a base address register to which was added the result of multiplying another register by an operand, plus another offset operand. All in one instruction.

I actually liked the MC680X0 assembler... :lol:

My favorite CPU architecture is the Cell BE. But that is a bit special, I admit.

My favorite detail of the ARM architecture are the conditional instruction prefixes, I included it in a CPU design of my own.
 

Linguofreak

Well-known member
Joined
May 10, 2008
Messages
5,036
Reaction score
1,273
Points
188
Location
Dallas, TX
Now, I mentioned "sane" above. x86 is insane. I am long past caring exactly how it does what it does. It is not "orthogonal" and some registers have special purposes and they're intimately related to addressing modes - segment registers, a sort of dedicated base address register.

Segment registers aren't tied into addressing modes very much. Instruction fetches always use CS, data references to memory almost always go through DS, stack operations always go through SS.

(This actually does get kind of cool with x86's execution level "rings" but was just a pain before the 80386.)

Actually, protected mode, with its new segmentation mechanism and privilege rings, was introduced with the 286. The problem was that the 286 wasn't fully back-compatible with the 8086 in protected mode, so protected mode wasn't used much before the 386 was introduced (because most software written for x86's at the time was for DOS and DOS had originally been written for the 8086). But the 386's segmentation mechanism was pretty much the same as the 286's except for being extended for 32-bit addresses.

The trend is toward fewer addressing modes and doing address calculation explicitly in honest code.

Well, until you get into paging... Very implicit, entirely in hardware.

---------- Post added at 12:50 ---------- Previous post was at 12:24 ----------

x86 is pure insanity. For starters, the operand order is backwards...

The operand order is just a feature of the assembly language, and doesn't necessarily represent the operand order in the underlying machine code. AT&T syntax uses the opposite operand order from the more typical Intel syntax (but has some other quirks).

In any case, the insanity of the x86 comes from the fact that its instruction set has accrued bit by bit starting with the 8008 (with which the 8086 was built to be assembly-language compatible, but not binary-compatible). The 8008 was an embedded controller for terminals and calculators. Modern x86's outperform mainframes of the 8008 era.
 
Top