Assembly x86-64 get function parameters from stack

主宰稳场 提交于 2021-01-19 08:38:07

问题


Lately I've been learning x86 Assembly from the book Programming from the Ground Up, but I have an x86-64 computer, so things start to go wrong at one point (pretty early in the book). I got to the part where I'm dealing with functions, specifically the power example. In this example he pushes the parameters onto the stack and then copies them into registers later in the function. Here's what his code looks like:

pushl $3                        # second argument
pushl $2                        # first argument
call power                      # call function
...
power:
  pushl %ebp                    # save old base pointer
  movl %esp, %ebp               # make stack pointer the base pointer
  subl $4, %esp                 # get room for our local storage

  movl 8(%ebp), %ebx            # put first argument in %eax
  movl 12(%ebp), %ecx           # put second argument in %ecx

Of course, this is 32-bit, and I'm running 64-bit, so I tried updating the registers and instruction suffixes to end up with something like this (comments shouldn't be needed this time):

pushq $3
pushq $2
call power
...
power:
  pushq %rbp
  movq %rsp, %rbp
  subq $4, %rsp

  movq 8(%rbp), %rdi
  movq 12(%rbp), %rsi

Given, I might just be confusing the actual registers I'm supposed to use, but I'm not completely sure. All I know is that when I print the value of %rdi in the GNU Debugger after the command movq 8(%rbp), %rdi it seems to me as if it has the memory address rather than the contents of it considering I get the following:

(gdb) i r rdi
rdi            0x400081 4194433

Also, is there something like a forum for Assembly hobbyists? I've done some basic searching but haven't managed to find one (except for a forum for x86 assembly that just has one post and it's a welcome post, http://www.x86-assembly.org/).

Thanks!


回答1:


The standard 64 bit conventions don't use the stack like that, they pass at least the first few arguments (type permitting) in registers. Of course for your own code you can still use the stack. However, you should adjust your offsets so that they use the appropriate size, 8 bytes instead of 4.

subq $4, %rsp

You should really use multiples of 8 unless you know what you are doing.

movq 8(%rbp), %rdi

You expect this to be the first argument but it isn't. It is actually the return address on the stack, since each item is 8 bytes now. So at 0(%rbp) you have the pushed rbp, and 8(%rbp) is the return address. Thus 16(%rbp) is the first argument and 24(%rbp) is the second.

Note that in most environments you can still write 32 bit code, so if you want to keep using that book you might want to do that instead of trying to adjust for 64 bit.

PS: You get a cookie for using a debugger :)



来源:https://stackoverflow.com/questions/37635864/assembly-x86-64-get-function-parameters-from-stack

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!