2

I finished reading PC Assembly Language and I was working on an implementation of RC4 encryption in Assembly. What I can't comprehend is why

mov eax, [edx+ecx]

works but

mov eax, [edx-ecx]

doesn't. The inline assembler gives me this error message,

non-constant expression in 'second operand'

What does that mean? Thanks in advance.

shebaw
  • 1,775
  • 1
  • 13
  • 15
  • In general, see [Referencing the contents of a memory location. (x86 addressing modes)](https://stackoverflow.com/q/34058101) for the available addressing modes. Only addition, but you can use a negative constant. – Peter Cordes Nov 09 '22 at 07:32

3 Answers3

7

There is an opcode for:

mov eax, [edx+ecx]

and there is an opcode which can be assembled from:

mov eax, [edx-CONSTANT]

because the assembler uses the regular opcode but negates the constant during assembly:

mov eax, [edx+(-CONSTANT)]

However there is not an opcode for:

mov eax, [edx-ecx]

So basically you're attempting to execute an instruction that doesn't exist.

John Lemberger
  • 2,689
  • 26
  • 25
5

The following gives a good summary of x86 addressing modes. Note that there is no "register minus register" form: Wikipedia.

As a workaround, you could negate the contents of ecx then use [edx+ecx] (you may have to negate it back if you need the original value afterwards).

NPE
  • 486,780
  • 108
  • 951
  • 1,012
1

You're not allowed to subtract in the offset like that. The intent is that you can point at the base of a memory buffer and then add an offset into it. Subtraction would result in pulling you out of the specified memory buffer...

Brian Knoblauch
  • 20,639
  • 15
  • 57
  • 92