2013-04-02 3 views
-3

J'essaie de comprendre le code de l'assembly lors d'un appel de fonction récursif.Attribution d'octets pour les variables locales d'une fonction et L'instruction POP n'est appelée qu'une seule fois

#include<stdio.h> 
int recursive(int no){ 
    if(no > 1){ 
    no--; 
    recursive(no); 
    printf("\n %d \n",no); 
    } 
    else if(no == 1){ 
    return 1; 
    } 
} 

int main(){ 
    int a = 10; 
    recursive(a); 
    return 0; 
} 

démontage:

.file "sample2.c" 
     .section  .rodata 
.LC0: 
     .string "\n %d \n" 
     .text 
.globl recursive 
     .type recursive, @function 
recursive: 
     pushl %ebp 
     movl %esp, %ebp 
     subl $24, %esp 
     cmpl $1, 8(%ebp) 
     jle  .L2 
     subl $1, 8(%ebp) 
     movl 8(%ebp), %eax 
     movl %eax, (%esp) 
     call recursive 
     movl $.LC0, %eax 
     movl 8(%ebp), %edx 
     movl %edx, 4(%esp) 
     movl %eax, (%esp) 
     call printf 
     jmp  .L5 
.L2: 
     cmpl $1, 8(%ebp) 
     jne  .L5 
     movl $1, %eax 
     movl %eax, %edx 
     movl %edx, %eax 
     jmp  .L4 
.L5: 
.L4: 
     leave 
     ret 
     .size recursive, .-recursive 
.globl main 
     .type main, @function 
main: 
     pushl %ebp 
     movl %esp, %ebp 
     andl $-16, %esp 
     subl $32, %esp 
     movl $10, 28(%esp) 
     movl 28(%esp), %eax 
     movl %eax, (%esp) 
     call recursive 
     movl $0, %eax 
     leave 
     ret 
     .size main, .-main 
     .ident "GCC: (Ubuntu/Linaro 4.4.4-14ubuntu5) 4.4.5" 
     .section  .note.GNU-stack,"",@progbits 

Je pouvais comprendre .LC0 tient toujours les chaînes littérales. Mais je ne sais pas ce que cela signifie vraiment. Aimeriez-vous comprendre le code lors de la récurrence de l'appel de fonction a été faite. Je ne pouvais pas comprendre ce que ce morceau de code assembleur fait,

 subl $24, %esp 
     cmpl $1, 8(%ebp) 
     jle  .L2 
     subl $1, 8(%ebp) 
     movl 8(%ebp), %eax 
     movl %eax, (%esp) 
     call recursive 
     movl $.LC0, %eax 
     movl 8(%ebp), %edx 
     movl %edx, 4(%esp) 
     movl %eax, (%esp) 
     call printf 
     jmp  .L5 
.L2: 
     cmpl $1, 8(%ebp) 
     jne  .L5 
     movl $1, %eax 
     movl %eax, %edx 
     movl %edx, %eax 
     jmp  .L4 

Q1: La fonction récursive contient 1 paramètre. Ainsi, après l'alignement de remplissage, il doit être 8. pourquoi il est 24.

Egalement dans .L2,

 movl $1, %eax 
     movl %eax, %edx 
     movl %edx, %eax 
     jmp  .L4 

Q2: nous sommes passés « 1 » à la accumulater, pourquoi nous déménagement à nouveau au registre de données, puis de nouveau à l'accumulateur.

Q3: Sommes-nous sortis de la pile. Si le congé est utilisé pour sortir de la pile, ne sommes-nous pas en train de faire sauter le reste des 8 cadres de la pile?

+4

Vous avez tout un tas de questions sans rapport avec essentiellement sur assembleur x86. Pourriez-vous éditer votre question afin de vous concentrer sur le problème ** un **? –

Répondre

1

Pour répondre à la seule chose dans votre message qui correspond à votre titre:

Pourquoi ne pas exorbités de la pile et Nsappuyez instruction dans l'assemblée.

Parce que leave équivaut à:

movl %ebp, %esp 
popl %ebp 
Questions connexes