1

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

在这本书(第 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
4

3 回答 3

2

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

于 2011-03-21T02:10:02.710 回答
1

我相信这一点:

 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

标签 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
于 2011-03-21T02:36:30.040 回答
1

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

[1] 我知道,我知道,但是让我们离开rep movs这个并保持简单。

于 2011-03-21T02:25:11.287 回答