Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 程序集中的返回地址_Assembly - Fatal编程技术网

Assembly 程序集中的返回地址

Assembly 程序集中的返回地址,assembly,Assembly,好吧,根据下面的程序。我似乎无法理解回信地址 这就是我目前的看法: 我们将4作为参数推送到堆栈上。这意味着我们的%esp增加了4 我们称之为factorial 将调用者basepointer推到堆栈上,使%esp再次增加4 将旧的堆栈指针移动到新的basepointer(%ebp) 取出调用者推送到堆栈上的参数movl8(%ebp),%eax 因此,当我们输入factorial时,%esp指向堆栈的顶部,即4 我们将旧的basepointer推到堆栈上,因此现在%esp指向旧的basepoin

好吧,根据下面的程序。我似乎无法理解回信地址

这就是我目前的看法:

  • 我们将
    4
    作为参数推送到堆栈上。这意味着我们的
    %esp
    增加了4
  • 我们称之为factorial
  • 将调用者basepointer推到堆栈上,使
    %esp
    再次增加4
  • 将旧的堆栈指针移动到新的basepointer(
    %ebp
  • 取出调用者推送到堆栈上的参数
    movl8(%ebp),%eax
  • 因此,当我们输入
    factorial
    时,
    %esp
    指向堆栈的顶部,即
    4

    我们将旧的basepointer推到堆栈上,因此现在
    %esp
    指向旧的basepointer

    我们将stackpointer值复制到basepointer寄存器(
    %ebp

    这意味着当前
    %esp
    %ebp
    指向堆栈顶部,该堆栈保存旧的
    %ebp

    这是堆栈的外观:

    ################
    # Parameter: 4 #
    #--------------#
    # Old %ebp     # <-- %esp, %ebp point here
    #--------------#
    
    但是,示例中使用的偏移量为8。返回地址是否隐式添加到堆栈中

    如果是这样,我是否应该使用旧的
    %ebp
    作为基础来解决它

    .section .data
    .section .text
    .globl _start
    .globl factorial
    
    _start:
        # Push the parameter.
        pushl $4    
        call factorial
        # Decrease the stackpointer to scrub
        # the parameter pushed before.
        addl $4, %esp
        # Move the result of the function
        # that is stored in %eax to %ebx
        # so we can return it.
        movl %eax, %ebx
        # Exit stuff.
        movl $1, %eax
        int $0x80
    
    .type factorial, @function
    factorial:
        ###################################
        # Standard function stuff.
        ###################################
        # Save caller basepointer.
        pushl %ebp
        # Set callee basepointer to stackpointer.
        movl %esp, %ebp
        ###################################
        # Fetch the first parameter and put
        # it in register %eax.
        movl 8(%ebp), %eax
        # If parameter is 1 return 1
        cmpl $1, %eax
        je end_factorial
    
        # Decrease our parameter.
        decl %eax
    
        ###################################
        # Recursive call
        ###################################
        # Push parameter.
        pushl %eax
        call factorial
        ###################################
    
        # We stored our own input on the stack
        # (pushl %eax). So we take that back
        # to multiply it with the result of the
        # recursive call which is stored in %eax
        movl 8(%ebp), %ebx
        # Multiply the result with
        # with our own parameter.
        imull %ebx, %eax
    
    end_factorial:
        # Default function exit stuff
        movl %ebp, %esp
        popl %ebp
        ret
    

    您的代码中似乎有一个bug。递归调用推送、调用和从不弹出。在主调用中,堆栈指针有一个子4。。。虽然在您的情况下,您希望在eax中弹出它(您不希望从该调用中修改它)

    ###################################
    #递归调用
    ###################################
    #推送参数。
    pushl%eax
    调用阶乘
    
    popl%eax是,返回地址由
    调用
    指令推送。
    .section .data
    .section .text
    .globl _start
    .globl factorial
    
    _start:
        # Push the parameter.
        pushl $4    
        call factorial
        # Decrease the stackpointer to scrub
        # the parameter pushed before.
        addl $4, %esp
        # Move the result of the function
        # that is stored in %eax to %ebx
        # so we can return it.
        movl %eax, %ebx
        # Exit stuff.
        movl $1, %eax
        int $0x80
    
    .type factorial, @function
    factorial:
        ###################################
        # Standard function stuff.
        ###################################
        # Save caller basepointer.
        pushl %ebp
        # Set callee basepointer to stackpointer.
        movl %esp, %ebp
        ###################################
        # Fetch the first parameter and put
        # it in register %eax.
        movl 8(%ebp), %eax
        # If parameter is 1 return 1
        cmpl $1, %eax
        je end_factorial
    
        # Decrease our parameter.
        decl %eax
    
        ###################################
        # Recursive call
        ###################################
        # Push parameter.
        pushl %eax
        call factorial
        ###################################
    
        # We stored our own input on the stack
        # (pushl %eax). So we take that back
        # to multiply it with the result of the
        # recursive call which is stored in %eax
        movl 8(%ebp), %ebx
        # Multiply the result with
        # with our own parameter.
        imull %ebx, %eax
    
    end_factorial:
        # Default function exit stuff
        movl %ebp, %esp
        popl %ebp
        ret
    
    ###################################
    # Recursive call
    ###################################
    # Push parameter.
    pushl %eax
    call factorial
    popl %eax    <-- this missing, right?
    ###################################
    
    Instructions                    Stack
    
    push $4                         00  0000:0004
    
    call factorial                  00  <IP after call>
                                    04  0000:0004
    
    push %ebp                       00  old ebp
                                    04  <IP after call>
                                    08  0000:0004