9

Are there any differences between

LEA $1000,A0

and

MOVE #$1000,A0

to put an address in the address registry?

Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
dynamic
  • 46,985
  • 55
  • 154
  • 231

5 Answers5

10

In this case, there will be no observable difference (unlike the accepted answer claims - the MOVE example will assemble as MOVEA which does not alter the CCR, see M68K Reference Manual Pg 4-116 to 4-120).

Durandal
  • 19,919
  • 4
  • 36
  • 70
6

The lea instruction does not affect flags, where the move instruction does. Specifically Z and C will be cleared after the move #$1000,a0.

Gunther Piez
  • 29,760
  • 6
  • 71
  • 103
  • @yes123 Nowadays I do rarely write something in assembly, but I still look quite often at the assembly generated by gcc - to check if it hasn't messed up again :-) But at the time I owned a 68k based computer (Atari ST :-)) writing assembly was a quite common task to speed up critical routines. – Gunther Piez May 25 '12 at 06:45
  • another little difference if you are interested to :) http://stackoverflow.com/questions/10766855/why-address-register-postincrement-is-a0 – dynamic May 26 '12 at 13:59
  • A different answer says this specific `move` won't affect flags (because it's writing an address register). – Peter Cordes Oct 28 '20 at 16:53
5

Durandal is correct, operations involving an address register have generally no impact on the processor flags, in this particular case the two instructions will behave the same and take the exact same cpu time (8 cycles using short addressing mode or 12 using long mode).

MOVE xx,an is not a real instruction, it's something assemblers allow but if you look at the disassembled result you will see that that the actual instruction is MOVEA.

1

The motivation of having LEA, instead of only MOVE, is that LEA gives access to the result of the address calculation based on the different addressing modes.

The MOVE #$1000,A0 instruction moves the immediate $1000 into the A0 register, since the immediate indication "#" is used in the mnemonic. The LEA $1000,A0 instruction points to the memory address $1000, and loads this address into the A0 register. In this simple example, the result is the same, and it looks like it is just a matter of some simple syntax with the missing immediate indication "#".

What LEA actually does may be easier to understand when looking at the difference in:

LEA (A0),A1

and:

MOVE (A0),A1

With LEA (A0),A1, the A1 register is loaded with the A0 value, like A1 := A0, where the MOVE (A0),A1 loads the word (default size) value from the memory location in the A0 register, sign extend the value to long (always entire register for address registers) and saves the value in the A1 register.

So LEA provides the address result from the address calculation before the address is used to actually make a memory access. This is also why there isn't any LEA #<data> format (addressing mode), since the address of the #<data> would be in the program space (PC relative), since immediate data is part of the instruction.

The real strength in LEA is apparent when when more complex addressing modes are used, where it would require significant code to calculate the address otherwise.

So the actual difference on LEA and MOVE in the original question can better be illustrated with this illegal code for address register destination (possible for data register destination):

LEA ($1000),A0

and:

MOVE #$1000,A0

This more clearly shows that LEA provides the address of the indirection, without actually doing the memory access.

Morten Zilmer
  • 15,586
  • 3
  • 30
  • 49
  • As you sure `LEA (A0),A1` is equivalent to a simple `A1 := A0` assignement ? I find it suprising since the `(A0)` is indirect addressing mode, one expect it to mean : *load the data pointed by `A0` into `A1`*. – XouDo Mar 25 '21 at 11:59
  • Ask yourself, what is the address of the indirection given by `(A0)`? And when `LEA` gives the address of the source argument, what is then the value of the source in `LEA (A0), ...`? – Morten Zilmer Mar 25 '21 at 19:12
  • I understand what you mean, but if `A0`'s value is just copied into `A1`, I can't figure out the meaning of the bracket notation `(A0)` here, except if `LEA` behavior *implies* extracting the address of the source argument. Considering this, what would `LEA Table,A0` (example from the documentation) do? (I guess each langage has its illogical/confusing features) – XouDo Mar 26 '21 at 09:35
  • 1
    The bracket notation in `(A0)` is an indirection, so when doing a `MOVE`, the data at the address given by `A0` is accessed. With respect to `LEA Table,A0`, then it means getting the address of `Table`, since table is an address value, and not an immediate, which is also covered in the answer above. You can try this out by downloading the [EASy68K](http://www.easy68k.com/) simulator. – Morten Zilmer Mar 26 '21 at 16:14
  • Note that `LEA ($1000).w,A0` and `LEA ($1000).l,A0` are actually valid effective addressing modes for LEA. – flamewing May 25 '21 at 07:50
  • Does this mean that `lea (A0),A1` is equivalent to `movea.l A0,A1`? I wonder if there is a case where I can't express a `lea` by some adjusted `movea`. I think `lea ($1234,A0),A0` might be one, but you could just use `adda.l #$1234,A0`. – Robert S. Nov 10 '22 at 22:13
0

When I was learning how to program in assembly language (68k) there was a difference pointed out in regards to this example of LEA and MOVE.L when it comes to dealing with Address Registers. In terms of using labels there is definitely a major difference.

Say you have a label Foo for some DC.*.

LEA Foo, A0       ;Loads Foo into Address Register A0

MOVE.L #Foo, A0   ;Loads Foo into Address Register A0

The lesson was that under normal conditions, the above two instructions would in fact accomplish the same thing. However, due to "relocatability" in real-life systems, the bottom one can cause problems.

It is safest to just use the LEA approach. Whether or not there can be an issue when using $1000 - I am not sure on. However, to talk about the difference between this LEA and MOVE.L when dealing with Address Registers this is definitely something that has to be considered.

Derek W
  • 9,708
  • 5
  • 58
  • 67
  • 1
    I don't think this statement is completely correct. There's indeed a different in 'relocability' but only if you had used the pc relative mode for lea. LEA Foo(pc),A0 is indeed position independent, but LEA Foo,A0 like move.l #Foo,A0 will have the assembler generate a relocation table for the label reference. Of course the pc relative version has some drawbacks, the referred label has to be at +/-32k bytes of the instruction. – Mickaël Pointier Feb 06 '14 at 08:26