Page 1 of 1

Why is CX not a valid index for addressing in 16-bit mode?

Posted: Mon Jan 27, 2014 7:15 pm
by Isaac
I wrote an assembly file which I tried assembling with NASM. The problem was this line:

Code: Select all

mov [ds:cx],0xee
where NASM said:

Code: Select all

error: invalid effective address
Here is another line in my code:

Code: Select all

mov [es:bx],0xff
Notice how I used BX instead. But, what is the difference between these two lines? Why does NASM only complain about the first one? Can't I set any register to whatever I want? Why does it make a difference which one I use?

Re: Why is CX not a valid index for addressing in 16-bit mod

Posted: Mon Jan 27, 2014 8:42 pm
by Minoto
Isaac wrote:Notice how I used BX instead. But, what is the difference between these two lines? Why does NASM only complain about the first one? Can't I set any register to whatever I want? Why does it make a difference which one I use?
In real mode, only a subset of the available registers can be used for address formation. Read the memory addressing section of the Real_Mode wiki page for more details, or look up the mod r/m byte and its role in addressing.

Re: Why is CX not a valid index for addressing in 16-bit mod

Posted: Mon Jan 27, 2014 9:44 pm
by azblue
^^What Minoto said.

The older processors weren't so flexible; your options are pretty much: BX, SI, DI, BP.

However, I'm fairly certain you can use ECX and all the other addressing modes you're used to even in Real Mode, so long as you don't cross 64K boundaries.

For example:

Code: Select all

and ecx, 0xffff
mov ax, [ecx] 
Or

Code: Select all

mov ax, [eax *4 +ecx] ;valid as long as eax*4+ecx <=64k

Re: Why is CX not a valid index for addressing in 16-bit mod

Posted: Mon Jan 27, 2014 10:15 pm
by Minoto
azblue wrote:However, I'm fairly certain you can use ECX and all the other addressing modes you're used to even in Real Mode, so long as you don't cross 64K boundaries.

For example:

Code: Select all

and ecx, 0xffff
mov ax, [ecx] 
Or

Code: Select all

mov ax, [eax *4 +ecx] ;valid as long as eax*4+ecx <=64k
Right -- all of the 32 bit registers, and the addressing modes you can form using them, are available in Real Mode; it just costs you a prefix byte, and you still have to stay within 64K segment limits. I probably should have clarified that I was speaking only about standard 16-bit addressing, where the register choices are limited to what the 8086 offered.

Re: Why is CX not a valid index for addressing in 16-bit mod

Posted: Tue Jan 28, 2014 5:31 am
by Bender
However, I'm fairly certain you can use ECX and all the other addressing modes you're used to even in Real Mode, so long as you don't cross 64K boundaries.
64K boundaries
Just wanted to ask a question about this (too small for another thread), isn't the 386 Real Mode same as the Protected Mode just that the segment
limits are 64KB, plus memory protection schemes are not available,
I think there is a hack which switches to protected mode and streches the segment limits to 4GB (?), so that you can access more that 1MB?
EDIT : Whoops sorry for being too ignorant, the hack was unreal mode.

Re: Why is CX not a valid index for addressing in 16-bit mod

Posted: Tue Jan 28, 2014 8:26 am
by Combuster
Isaac wrote:Can't I set any register to whatever I want? Why does it make a difference which one I use?
16-bit mode didn't quite have "general purpose" registers, but rather many were designed for a certain task. To make typical instructions shorter, they removed AX, CX and DX from addressing modes, and replaced them with the composites BX+SI and BX+DI so you can have a separate pointer and index in a register.

Re: Why is CX not a valid index for addressing in 16-bit mod

Posted: Tue Jan 28, 2014 5:40 pm
by Isaac
So certain registers can't do certain things. Hmm... interesting. And I can use EAX in real mode, but I just won't be able to store a value over 0xffff. Right?

Anyway, which registers can I use for addressing memory? Why doesn't th CPU let me use other registers (like CX)? Is there some history behind that?

Re: Why is CX not a valid index for addressing in 16-bit mod

Posted: Tue Jan 28, 2014 5:50 pm
by azblue
sid123 wrote: Just wanted to ask a question about this (too small for another thread), isn't the 386 Real Mode same as the Protected Mode just that the segment
limits are 64KB, plus memory protection schemes are not available,
I think there is a hack which switches to protected mode and streches the segment limits to 4GB (?), so that you can access more that 1MB?
EDIT : Whoops sorry for being too ignorant, the hack was unreal mode.
Yup, in unreal mode you're no longer limited to the 64K boundaries; you can use all the normal 32-bit addressing modes you'd have in protected mode with no restrictions.

Re: Why is CX not a valid index for addressing in 16-bit mod

Posted: Tue Jan 28, 2014 5:53 pm
by azblue
Isaac wrote:So certain registers can't do certain things. Hmm... interesting. And I can use EAX in real mode, but I just won't be able to store a value over 0xffff. Right?
You can store whatever you want in EAX, even while in real mode; you just have to stick to under 64K if you use it to access memory.

For example:

Code: Select all

mov eax, 0x12345678 ;this is OK in real mode

mov ebx, [eax] ;this is NOT OK in real mode, because EAX < 64K 

Re: Why is CX not a valid index for addressing in 16-bit mod

Posted: Wed Jan 29, 2014 8:19 pm
by mathematician
Isaac wrote:Why doesn't th CPU let me use other registers (like CX)? Is there some history behind that?
The history is that the original 8086 could only access memory through bx, si, di, bx+si or bx+di, maybe with an offset added, such as bx+si + 8. The old timers such as me, still tend to rely upon those three registers, even though I know the others are available in protected mode.

Re: Why is CX not a valid index for addressing in 16-bit mod

Posted: Wed Jan 29, 2014 10:20 pm
by Minoto
mathematician wrote:The history is that the original 8086 could only access memory through bx, si, di, bx+si or bx+di, maybe with an offset added, such as bx+si + 8.
Almost -- any one, two, or all three of (bx or bp) + (si or di) + offset.