2

Why does the indexer in indirect addressing have to be a dword?

For example, this doesn't work:

.data
arr dword 10 dup(?)
.code
...
mov bx, 2
call [arr+bx*4] ;;error A2032:invalid use of register

But using ebx instead of bx would work, why?

shinzou
  • 5,850
  • 10
  • 60
  • 124
  • 4
    There is no reason other than this is how the instruction set has been defined. See the [basic architecture manual](http://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-vol-1-manual.pdf), section _3.7.5 Specifying an Offset_. – Jester Jun 18 '16 at 11:38

1 Answers1

4

Because not all the 24 addressing modes have been introduced at the same time, some are not available with 16 bits registers.

In an instruction the addressing mode is encoded within the bytes modRM and SIB:

Instruction format

The possible 16 bit addressing modes are:

16-bits addressing modes

As you can see, there is no [bx*4] + disp16, for that a SIB would be needed, but SIB can only specify 32 bits registers (64 bits registers with a REX prefix):

SIB encodings


You can find all the relevant technical notes on Intel manual 2

Margaret Bloom
  • 41,768
  • 5
  • 78
  • 124
  • Later-introduced addressing modes could have been introduced to allow e.g. 16bit registers when address-size = 32b. The main reason is that it would be a waste of bits in the encoding, and a 2-bit scale for the index is more valuable than allowing mixed register sizes, or disp32 + r16. – Peter Cordes Jun 18 '16 at 11:53
  • Oh, actually I see how this works as an answer. The OP is probably using a 16bit address-size, and is just running into the limitations of 16bit addressing modes (no scale factors, so it doesn't matter which reg is index or base, as long as you don't try to use `[di+si]`). It is irvine32, though. – Peter Cordes Jun 18 '16 at 11:56
  • @PeterCordes :) Well, my point is not why Intel didn't introduced 16bits registers in 32 bits addressing modes; I agree with your conclusion but that's their call in the end. My point is that you simply can't, as today, encode a thing like `[bx*4]+disp16/32` and I felt that an over-simplified bit of history could help. – Margaret Bloom Jun 18 '16 at 12:06