Это в AT & T синтаксисПереход от Ассамблеи на C код
.global bar
.type bar, @function
bar:
pushl %ebp
movl %esp, %ebp
pushl %ebx
subl $20, %esp
movl 8($ebp), %ebx
movl $1, %eax
cmpl $1, %ebx
jle .L3
leal -1(%ebx), %eax //subtracts 1 from ebx and stores into eax
movl %eax, (%esp) //putting on stack frame
call bar //recursive call
addl %ebx, %eax // adds %ebx and %eax
.L3 //returns %eax
addl $20, %esp
popl %ebx
popl %ebp
ret //end of bar
Так что я думаю, что здесь происходит в основном он проверяет,% EBX является < = 1, и если он есть, он возвращается один. в противном случае он вызывает bar с x--;
Так что мой C код:
int bar (int x)
{
if (x<= 1)
return 1;
else
return x + bar(x-1);
}
Рекурсивный вызов действительно обманывая меня здесь. Я понимаю, что он вызывает бар с новым регистром% eax (который в основном становится x-1). Так оно просто возвращает сумму чисел?
Я не вижу, где вы получите 'x + (x-1)' для аргумента рекурсивного вызова. Там есть 'add' * after *, который вы, кажется, смешиваете с тем, что происходит * перед * вызовом. 'leal -1 (% ebx),% eax' является * инструкцией по эффективному адресу * загрузки. Он задокументирован в руководстве x86 (много он-лайн). Он используется для хранения адреса со смещением, но здесь, как это иногда бывает, он используется для сохранения одной инструкции, делая шаг и постоянное добавление за один раз. Я не вижу, где происходит * добавление 'eax' в стек *. Вы должны означать * переместить * его в стек, который необходимо передать ему как arg для 'bar'. – lurker
@ lurker Я понял, что испортил рекурсивный вызов, я работаю над его повторной обработкой. команда leal вычитает 1 из ebx и сохраняет ее в eax, хотя правильно? – bkennedy
Да, это правильно. – lurker