Home > Mobile >  How to offset from a local variable using x64 Assembly?
How to offset from a local variable using x64 Assembly?

Time:11-25

I'm trying to access a second local variable on the current stack frame, located at (I think?) %rsp-8, since the first is located at %rsp. What I'd like to do is load the address at %rsp-8 into another register. Note that this means the address that's currently stored at rsp, and not the data at that address in memory. Is it possible to do this without having to declare a separate register that stores the offset (or increments the current rsp)?

What I currently have:

...
    movq %rsp, %rsi             # Move the first address at rsp into rsi.
    leaq infmt, %rdi            # Load the input format string into rdi.
    movq $0, %rax               # Clear rax since it is a var-args procedure.
    call scanf
    movq %rsp, %rbx
    addq $8, %rbx
    movq %rbx, %rsi            # Move the next address at rsp into rsi.
    leaq infmt, %rdi           # Reload the input format.
    call scanf
...

What would be nice to have:

...
    movq %rsp, %rsi             # Move the first address at rsp into rsi.
    leaq infmt, %rdi            # Load the input format string into rdi.
    movq $0, %rax               # Clear rax since it is a var-args procedure.
    call scanf
    movq %rbx-8, %rsi           # Move the next address at rsp into rsi.
    leaq infmt, %rdi            # Reload the input format.
    call scanf
...

CodePudding user response:

You can add a value to a register with leaq using a displacement. Instead of this:

movq %rsp, %rbx
addq $8, %rbx
movq %rbx, %rsi

you can do this:

leaq 8(%rsp), %rsi

While this looks like a register dereference that would normally be used with movq, with leaq it just uses the value of %rsp and adds the displacement.

This can also be used with negative values, e.g. -8(%rsp) since you mentioned you needed %rsp-8.

  • Related