【问题标题】:assembly function flow装配功能流程
【发布时间】:2011-03-21 02:03:25
【问题描述】:

我正在阅读一本“从头开始编程”,如果你不知道这本书是什么,你仍然可以帮助我。

在这本书(第 4 章)中有两件事我不明白:

  1. movl %ebx, -4(%ebp) #store current result 做什么。
  2. “当前结果”是什么意思

在下面代码的标记部分,有:

movl 8(%ebp), %ebx

意思是把8(%ebp)保存到%ebx,但是我不明白的原因是,如果程序员想让8(%ebp)保存到-4(%ebp),为什么要把8(%ebp)传递给%ebx ?是“movl 8(%ebp), -4(%ebp)”吗?或者movl 8(%ebp), %ebx #put first argument in %eax 有错别字吗? (我认为%ebx 应该是%eax,反之亦然)

#PURPOSE: Program to illustrate how functions work
# This program will compute the value of
# 2^3 + 5^2
#Everything in the main program is stored in registers,
#so the data section doesn’t have anything.

.section .data
.section .text
.globl _start

_start:

pushl $3 #push second argument
pushl $2 #push first argument
call power #call the function
addl $8, %esp #move the stack pointer back
pushl %eax #save the first answer before

#calling the next function

pushl $2 #push second argument
pushl $5 #push first argument

call power #call the function
addl $8, %esp #move the stack pointer back
popl %ebx #The second answer is already

#in %eax. We saved the
#first answer onto the stack,
#so now we can just pop it
#out into %ebx

addl %eax, %ebx #add them together
#the result is in %ebx

movl $1, %eax #exit (%ebx is returned)
int $0x80

#PURPOSE: This function is used to compute
# the value of a number raised to
# a power.

#INPUT: First argument - the base number
# Second argument - the power to
# raise it to
#
#OUTPUT: Will give the result as a return value
#
#NOTES: The power must be 1 or greater
#
#VARIABLES:
# %ebx - holds the base number
# %ecx - holds the power
#
# -4(%ebp) - holds the current result
#
# %eax is used for temporary storage
#

.type power, @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
movl %ebx, -4(%ebp) #store current result

##########################################

power_loop_start:
cmpl $1, %ecx #if the power is 1, we are done
je end_power
movl -4(%ebp), %eax #move the current result into %eax
imull %ebx, %eax #multiply the current result by

#the base number
movl %eax, -4(%ebp) #store the current result
decl %ecx #decrease the power
jmp power_loop_start #run for the next power

end_power:
movl -4(%ebp), %eax #return value goes in %eax
movl %ebp, %esp #restore the stack pointer
popl %ebp #restore the base pointer
ret

【问题讨论】:

  • 我发现ref.x86asm.net 是一个很好的 x86/x86-64 指令参考。您会看到,没有任何形式的 mov 指令可以在两个内存操作数之间移动(正如 Greg 和 Stephen 都回答的那样)。

标签: function assembly flow


【解决方案1】:

许多汇编操作码只接受 一个 内存操作数(源或目标)。这可能解释了为什么从内存到内存的移动是通过 %ebx 完成的。

【讨论】:

    【解决方案2】:

    我相信这一点:

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

    是一个错字,应该是:

     movl 8(%ebp), %ebx #put first argument in %ebx  
    

    如果你注意到了,后来代码是正确的:

     movl %ebx, -4(%ebp) #store current result
    

    最后,作者也可以使用%eax 进行此操作(而不是%ebx),他没有理由不这样做,因为它根本不会改变程序。

    但评论可能会更清晰,我相信这也是一个错字。此时,最好写成:#storing 1st argument on the local stack frame

    label power_loop_start 使用该变量并将其临时存储在%eax 中以进行快速操作,然后将其放回堆栈上的相同位置以进行下一个循环:

     movl %eax, -4(%ebp)   #store the current result
     decl %ecx             #decrease the power
     jmp  power_loop_start #run for the next power
    

    【讨论】:

      【解决方案3】:

      正如 Greg 所暗示的,x86 与大多数主流架构一样,没有将数据从内存复制到内存的指令[1]。因此,您必须使用单独的 loadstore 复制数据。首先将数据从源内存加载到寄存器中,然后将数据从该寄存器存储到目标内存。这就是这里发生的一切。

      [1] 我知道,我知道,但是让我们把 rep movs 排除在外,让事情变得简单。

      【讨论】:

      • 只是添加到注释1,可以推送abc;弹出定义;太
      猜你喜欢
      • 2013-02-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-20
      • 1970-01-01
      • 2015-05-13
      • 2011-09-14
      • 1970-01-01
      相关资源
      最近更新 更多