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

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
Isaac
Member
Member
Posts: 66
Joined: Sat Dec 07, 2013 7:08 pm

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

Post 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?
User avatar
Minoto
Member
Member
Posts: 89
Joined: Thu May 12, 2011 7:24 pm

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

Post 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.
Those who understand Unix are doomed to copy it, poorly.
azblue
Member
Member
Posts: 147
Joined: Sat Feb 27, 2010 8:55 pm

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

Post 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
User avatar
Minoto
Member
Member
Posts: 89
Joined: Thu May 12, 2011 7:24 pm

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

Post 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.
Those who understand Unix are doomed to copy it, poorly.
User avatar
Bender
Member
Member
Posts: 449
Joined: Wed Aug 21, 2013 3:53 am
Libera.chat IRC: bender|
Location: Asia, Singapore

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

Post 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.
"In a time of universal deceit - telling the truth is a revolutionary act." -- George Orwell
(R3X Runtime VM)(CHIP8 Interpreter OS)
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

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

Post 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.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
Isaac
Member
Member
Posts: 66
Joined: Sat Dec 07, 2013 7:08 pm

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

Post 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?
azblue
Member
Member
Posts: 147
Joined: Sat Feb 27, 2010 8:55 pm

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

Post 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.
azblue
Member
Member
Posts: 147
Joined: Sat Feb 27, 2010 8:55 pm

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

Post 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 
User avatar
mathematician
Member
Member
Posts: 437
Joined: Fri Dec 15, 2006 5:26 pm
Location: Church Stretton Uk

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

Post 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.
The continuous image of a connected set is connected.
User avatar
Minoto
Member
Member
Posts: 89
Joined: Thu May 12, 2011 7:24 pm

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

Post 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.
Those who understand Unix are doomed to copy it, poorly.
Post Reply