j'ai utilisé la pile dans Assembly mais je n'ai aucune idée de Push ebp et pop ebp.
.intel_syntax noprefix
.include "console.i"
.text
askl: .asciz "Enter length: "
askb: .asciz "Enter breadth: "
ans: .asciz "Perimeter = "
_entry:
Push ebp # establishing stack-frame
mov ebp, esp
sub esp, 12
Prompt askl
GetInt [ebp-4] # length
Prompt askb
GetInt [ebp-8] # breadth
mov eax, [ebp-4] # eax = l
add eax, [ebp-8] # eax = l + b
add eax, eax # eax = 2 * (l + b)
mov [ebp-12], eax
Prompt ans
PutInt [ebp-12]
PutEoL
mov esp, ebp
pop ebp # unwinding stack-frame
ret
.global _entry
.end
Je ne sais pas si c'est votre doute, mais vous vous demandez peut-être à ce sujet:
Push ebp
mov ebp, esp
sub esp, 12
Les 2 premières lignes sont appelées fonction d'assemblage prologue. Il stocke le pointeur de base précédent (ebp) et définit le pointeur de base comme il était en haut de la pile. Cela signifie que tout le contenu de la pile est enregistré dans la pile, de sorte que la fonction peut pousser/sauter dans la pile.
Le sub esp,12
line économise de l'espace pour les variables locales dans la fonction.
À la fin, vous avez:
mov esp, ebp
pop ebp
ret
C'est l'inverse du prologue, donc le contexte précédent peut être restauré.
Est-ce là votre doute? :)
ebp
est appelé pointeur de base ou pointeur de cadre. En entrant dans votre fonction, vous appuyez dessus (pour enregistrer la valeur de la fonction appelante). Ensuite, vous copiez esp
, le pointeur de pile, dans ebp
, de sorte que ebp
pointe désormais vers le cadre de pile de votre fonction. À la fin de votre fonction, vous pop puis ebp
afin que la valeur de la fonction appelante soit restaurée.
Pour des éclaircissements sur ce qui se passe exactement - l'instruction Push
place la valeur du registre spécifié (ebp
dans ce cas), sur la pile, et décrémente le pointeur de pile de la quantité appropriée . L'opération pop
est l'inverse - elle incrémente le pointeur de pile et prend une valeur de la pile et la place dans le registre spécifié.