Ret и рекурсивный вызов функции - Assembler

Узнай цену своей работы

Формулировка задачи:

Данный код вычисляет f(n)=1+2+3+...+n, т.е. сумму арифметической последовательности до n. Вычисление производится рекурсивно в функции f(n).
.intel_syntax noprefix
.text
.global main
main:
        //n=10
        mov eax,10
//eax<-f(n)
        push eax
        call f
        add esp,4
 
//printf("Wynik = %1",eax);
        push eax
        mov ebx,offset message
        push ebx
        call printf
        add esp,8
 
        mov eax,0
        ret
 
                             f:
                                mov eax,[esp+4]
                                cmp eax,1
                                jnz ety1
                                mov eax,1
                                ret
                                ety1:
                                push ebx
                                mov ebx,eax
                                dec eax
                                push eax
                                call f
                                add esp,4
                                add eax,ebx
                                pop ebx
                                ret
 
        .data
         message:
        .asciz "Result = %i\n"
Подскажите, что именно записывает в регистр сдедующая строка кода? Как я понимаю она записывает то что находится под данным адресом [esp+4], а там находится число 10, зачем нам его туда заносить если мы его уже занесли в регистр eax?????
mov eax,[esp+4]
Далее сравниваем содержимое регистра с 1:
 cmp eax,1
Если не равняются, т.е. разница не равна 0 то делаем "прыжок" к ety1. Т.е. тут проверяем не равняется ли 1 наш аргумент:
jnz ety1
Допустим аргумент не равнялся 1.Кладем на стек регистр:
push ebx
В него записываем значение eax:
mov ebx,eax
Декрементируем eax и кладем его на стек:
dec eax
push eax
Потом снова вызываем функцию f. Т.е. рекурсивно вызываем функцию.А вот ондна из главных непоняток, где мы теперь окажемся после вызова функции?????????????????????? В сторочке 23.
call f
Если так, то снова проверяем не 1 ли аргумент, потом все тоже самое и снова вызываем функцию.
call f
Тогда когда мы вообще окажемся в участке кода, который следует после рекурсивного вызова функции т.е. когда мы окажемся тут?????????????????????????????????????
add esp,4
add eax,ebx
 pop ebx
И еще в какой конкретно участок кода нас возвращает ret???????????

Решение задачи: «Ret и рекурсивный вызов функции»

textual
Листинг программы
add  esp, 4    ; увеличиваем адрес стека на 4, для получения адреса метки (esp=@@)(esp+4).
    jmp  [esp]       ; прыжок на метку @@.

Объяснение кода листинга программы

В данном коде происходит следующее:

  1. add esp, 4 - увеличиваем адрес стека на 4, для получения адреса метки (esp=@@)(esp+4).
  2. jmp [esp] - прыжок на метку @@. Список переменных и их значений:
  3. esp - адрес стека, содержит значение @@.
  4. [esp] - значение в памяти по адресу esp, содержит метку @@.

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

7   голосов , оценка 3.714 из 5