1

I'm trying to write a subroutine that adds two large numbers in x86 assembly (MASM). The numbers are pointed at by the si and di registers, and the function should iterate from right to left, adding each data word and passing the carry, and saving the result in di. The number of data words to add is determined by a previous chunk of code.

...
    mov       cx, ( number of data words to add )
adding:
    mov       bx,cx               ;copy the loop counter to bx
    lea       ax,[di+2*bx]        ;move ax to the destination word
    adc       ax,[si+2*bx]        ;add the source word into the destination word
    loop      adding              ;main sub loop
...

Unfortunately, when I try to compile this code, I get error A2032: invalid use of register on both the lea and adc lines. What is wrong with the syntax that I'm using?

Aki Suihkonen
  • 19,144
  • 1
  • 36
  • 57
Otaia
  • 441
  • 3
  • 14
  • 1
    Duplicate question. Summary: register*2 is a feature of 80386+ and it uses 32-bit registers. Also use mov instead of lea. – Aki Suihkonen Mar 12 '13 at 05:45
  • Modified the title: original title had very little to do with the problem. That's also the problem with the dozen duplicates of this question -- this is a biweekly recurring theme. – Aki Suihkonen Mar 12 '13 at 06:51

1 Answers1

3

The original 8086 addressing modes are limited to the combinations in this chart:

     (disp)   (base)   (offset)
 mov [1234] + [bx]  +  [si], ax
              [bp]  +  [di]

One must choose maximum of one item from each group (displacement, base and offset). No other combination is valid.

The 80386 addressing modes were extended towards more orthogonal:

 mov  al, byte ptr [12345] + [esp + 8 * eax];

Here the index registers are all 32-bit, esp can be used to point directly to stack variables, and the scaling term has legal values of 1,2,4 and 8. With this many combinations the instruction LEA can be used to perform a single instruction orthogonal 3-parameter addition without changing flags: [reg1] = [reg2] + [reg3]; and to perform some other arithmetic, such as multiplying register by a factor of 3,5 or 9.

Without 32-bit addressing modes one has to emulate the scaling e.g. with

     mov bx, (N-1)*2          // constant expression
 a:  mov ax, [bx + di]
     adc ax, [bx + si]
     sub bx, 2
     jns a

See also purpose of LEA instruction.

Community
  • 1
  • 1
Aki Suihkonen
  • 19,144
  • 1
  • 36
  • 57
  • Worth noting that even on a 386-compatible CPU, 16-bit addressing modes still have the same limitations, because the binary machine-code encoding is the same. (No SIB byte, so all addressing modes have to be encoded into the ModR/M byte). Also see this larger [answer detailing all the x86 addressing modes](http://stackoverflow.com/questions/34058101/referencing-the-contents-of-a-memory-location-x86-addressing-modes/34058400#34058400) that I wrote up. – Peter Cordes Aug 13 '16 at 15:27