Noam Solovechick
Noam Solovechick

Reputation: 1147

ADD instruction or plus sign?

Very simble question, yet I didn't find a good answer so I'm asking here.
I see that sometimes for addition we use the ADD instruction, and sometimes I see the use of the plus sign (+).
Please look at the following:

mov eax,[esi + TYPE DWORD]

Well, I learned that for adding numbers I should use the ADD instruction, yet it seems to work like this.
I thought it should have been done this way:

add esi, TYPE DWORD
mov eax,[esi]
sub esi, TYPE DWORD

I mean, how can the computer access the memory address esi + TYPE DWORD without doing an add instruction? so odd...

Thank you so much for reading (:

Upvotes: 3

Views: 2267

Answers (2)

Mike
Mike

Reputation: 2761

To go a little more generic, what you are looking at in the first example is part of the addressing mode, not an op-code.

The simplest form of address registers is simply a pointer to what you're interested in (the base address)

[bx]

If you were looking at an array or a structure then you would have to adjust the base register to look at anything else. Time moved on and addressing became more flexible. You could have a base and an index:

[ebx+eax]    ; add 2 registers to get the pointers - array + index

Now, if you have an array of bytes you can keep the base and adjust the index. If you are looking at 2, 4 or 8 bytes you can adjust the index by the size of the target:

[ebx+eax*2]   ; 2 byte target, array + (index*2)

Now, if you're looking at a c-style structure then you can add a displacement to the resulting address, too:

[ebx+eax*2+16]

These are encoded into the instruction at compile time, not turned into assembler instructions. Familiarize yourself with addressing modes - they will save you a lot of time if you use the right mode for the right solution.

Upvotes: 3

Leeor
Leeor

Reputation: 19736

First of all, these are encoded as two different things - the ADD is an instruction, will come with a full opcode, while the + will be translated by your assembler into referencing mode for the main instruction it's attached to (MOV in this case).

The main difference however is that the first will be performed by the memory unit (or more accurately - the address generation unit), without consuming any additional arbitration on top of the load execution, while the latter will be performed over the ALU, and consume the required resources accordingly (depending on the micro architecture, but in your example, on any modern out-of-order CPU that would take at least a few queue entries, decode slots, scheduling slots, ports, etc..).

In that sense the first is often "cheaper", which is why it's often used even for normal arithmetic operations without memory referencing, by using a LEA instruction, as Harold pointed out.

Upvotes: 3

Related Questions