4
votes

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. ;)

2
movl src, dest means dest = src. leal src, dest means dest = &src (i.e dest = address of src)Sam
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

2 Answers

2
votes

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.

2
votes

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.