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%esp
再次增加4%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