Question

Je suis en train de lire une « programmation à partir du sol », si vous ne savez pas ce que ce livre est, vous pouvez toujours me aider.

il y a 2 choses que je ne comprends pas dans ce livre (chapitre 4):

  1. ce movl %ebx, -4(%ebp) #store current result pour.
  2. et ce qui ne signifie "résultat courant"

dans la section marquée du code, il y a:

movl 8(%ebp), %ebx

qui 8(%ebp) les moyens sauver à %ebx, mais la raison pour laquelle je ne comprends pas, si le programmeur manque 8(%ebp) pour sauver à -4(%ebp), pourquoi devrait 8(%ebp) être passé par %ebx? Est-akward "de movl 8(%ebp), -4(%ebp)"? Ou est-il une faute de frappe dans movl 8(%ebp), %ebx #put first argument in %eax? (Je pense que %ebx devrait être %eax ou vice versa)

#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
Était-ce utile?

La solution

Je crois que ceci:

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

était une faute de frappe, et il devrait vraiment être:

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

et si vous avez remarqué, plus tard, le code est correct:

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

En fin de compte, l'auteur aurait pu %eax utilisé pour cette opération ainsi (au lieu de %ebx), il n'y a aucune raison pour laquelle il ne devrait pas, car il ne modifierait pas le programme du tout.

Mais le commentaire pourrait être beaucoup plus clair et je crois que cela est une faute de frappe aussi bien. À ce stade, il serait mieux si elle a dit: #storing 1st argument on the local stack frame.

étiquette power_loop_start utilise cette variable et temporairement stocke dans %eax pour les opérations rapides, puis placez-le sur le même emplacement sur la pile pour la boucle suivante:

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

Autres conseils

De nombreux opcodes de montage acceptent que un opérandes de mémoire (soit source ou destination). Cela explique probablement pourquoi un passage de la mémoire à la mémoire se fait à travers% EBX.

Greg insinué, x86, comme la plupart des architectures traditionnelles, ne dispose pas d'une instruction qui copie les données de la mémoire à la mémoire [1]. Ainsi, vous devez copier les données via un réseau séparé charge et magasin . D'abord, vous chargez les données de la mémoire source dans un registre, vous stockez les données de ce registre à la mémoire de destination. C'est tout ce qui se passe ici.

[1] Je sais, je sais, mais Quittons rep movs de cela et garder les choses simples.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top