2011-03-21 72 views
1

我正在閱讀「從頭開始編程」,如果您不知道本書是什麼,那麼您仍然可以幫助我。彙編函數流程

在這本書中(第4章)有2個東西,我不明白:

  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 
+0

我發現HTTP:/ /ref.x86asm.net/是x86/x86-64的重要指令參考。您會看到,沒有任何形式的mov指令會在兩個內存操作數之間移動(正如Greg和Stephen都回答的那樣)。 – 2011-03-21 02:31:03

回答

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 
+0

我在第5章,順便說一句。 – karlphillip 2011-03-21 02:37:24

+0

非常感謝你,現在我可以繼續閱讀 – 2011-03-21 04:10:49

2

許多組件的操作碼只接受一個存儲器操作數(源或目標)。這可能解釋了爲什麼從內存移動到內存是通過%ebx完成的。

1

As Greg暗示,x86與大多數主流架構一樣,沒有將數據從內存複製到內存的指令[1]。因此,您必須使用單獨的加載商店複製數據。首先將源存儲器中的數據加載到寄存器中,然後將該寄存器中的數據存儲到目標存儲器中。這就是這裏發生的一切。

[1]我知道,我知道,但讓我們離開rep movs出來,並保持簡單。

+0

只是爲了加註1,可以推abc;流行音樂也 – BlackBear 2011-03-21 17:22:00