4

I know that the sentence I am about to say is probably the best way to become very unpopular on StackOverflow very quickly. I'll say it anyway: Why doesn't this work (completly)?

I was trying to figure out what the lea/leal instruction does. The way I understand it, lea/leal finds out the memory address of the first operand and writes this address into the second operand (which might be a register or so).

This part seems to work. When I run the program below it says:

The memory address of var is 134518204.

However, right after this it says something like "memory access error". pushl (%eax) obviously doesn't work. Why not?

.data
    var:    .long 42
    str1:   .string "The memory address of var is %d.\n"
    str2:   .string "At this memory address we find var's value: %d.\n"

.text
.global main
main: 
    leal var, %eax          # Copy the address of var into %eax
    pushl %eax
    pushl $str1
    call printf             # Print str1
    pushl (%eax)
    pushl $str2
    call printf             # Print str2

    # Some stack cleaning should be here :)

    movl $1, %eax
    int $0x80

I am not even sure if I got right what lea/leal does. Help is appreciated. ;)

lkbaerenfaenger
  • 5,652
  • 5
  • 21
  • 33
  • 1
    `movl src, dest` means `dest = src`. `leal src, dest` means `dest = &src` (i.e dest = address of src) – Sam Nov 02 '13 at 17:22
  • To be more accurate, `movl` evaluates the source, treats it as an address and moves it's contents to destination. But, `leal` evaluates the source and moves the evaluated value to destination. – Sam Nov 02 '13 at 17:25
  • possible duplicate of [What's the purpose of the LEA instruction?](http://stackoverflow.com/questions/1658294/whats-the-purpose-of-the-lea-instruction) – phuclv Mar 12 '15 at 09:32

2 Answers2

2

The way I understand it, lea/leal finds out the memory address of the first operand and writes this address into the second operand (which might be a register or so).

Sounds accurate enough. It's used to perform address arithmetic; which can be as simple as just loading an address, but you can also use it to perform multiplication by certain constants.


pushl (%eax) obviously doesn't work. Why not?

Your push instruction is not referencing the address you think it does: printf returns the number of characters written, and that value is returned in the %eax register, so %eax no longer contains the address of var.

Michael
  • 52,337
  • 9
  • 68
  • 113
  • Thank you so much! I actually just read that according to the C Calling Convention, %eax will ALWAYS be changed. Seems like I really need to do something else for a while... :D – lkbaerenfaenger Nov 02 '13 at 15:59
2

lea is usually (ab)used for calculations: if you just want the address of a global in a register, movl $var, %eax is clearer (and a byte shorter) than the lea.

Also, to make it clear, the destination operand of lea must be a register.

gsg
  • 8,645
  • 1
  • 18
  • 23