Рекурсия в asm процедуре\функции[Решено]
Добавлено: 13.03.2011 17:50:28
Собственно хотел спросить, как это реализовывать, во всех книгах по ассемблеру, пишут именно про ассемблерные функции, в которых есть вызов CALL и возврат RET.
А как быть с функциями, более высокого уровня.? Нигде об этом нормально не написано, по этому решил спросить.
Методом изучения исходников (асм кода) который генерирует FPC с ключами типа:
Сделал вывод, что вызов происходит с указанием имени функции при помощи CALL.
Провел эксперимент:
Функция расчета факториала:
Она же переписанная мною на асм:
Проверка:
Дает верный результат….
Вопрос: Получается что вызов функции, по идее сопровождается простым вызовом оператора CALL. Но до этого мы как бы сами должны приготовить входные параметры ? Скажем у меня все просто нужно только положить число в EAX…(потому что Avalue должно лежать там)и просто вызвать функцию, после вызова, нужно знать где будет лежать результат… Для процедур которые используют параметры из стека (pascal вызов) мы сами должны будем приготовить стек…?
Но мы получается используем стек одной и той же функции… или это так и происходит, Не будет ли переполнения?...
Вопрос №2:
Вот если это так, например просто не понятно, что вложить в стек в этом случае...Различие стека в Delphi and FPC что за результ ($Result) там лежит….
в той теме было сказано что:
Если это баг или неизвестно что туда положить, можно пока обойтись соглошением register. Но чтобы это работало хотябы при соглашении register, я должен разобраться с вопросом №1.
Спасибо за любые наводки по этому вопросу…
А как быть с функциями, более высокого уровня.? Нигде об этом нормально не написано, по этому решил спросить.
Методом изучения исходников (асм кода) который генерирует FPC с ключами типа:
- Код: Выделить всё
-Amasm -al –s
Сделал вывод, что вызов происходит с указанием имени функции при помощи CALL.
Провел эксперимент:
Функция расчета факториала:
- Код: Выделить всё
function Factorial(AValue: Cardinal): Cardinal;
begin
if AValue <=1 then
Result:=1
else
Result:=AValue*Factorial(AValue-1)
end;
Она же переписанная мною на асм:
- Код: Выделить всё
function Factorial2(AValue: Cardinal): Cardinal; register;assembler;
{$ASMMODE Intel}
asm
cmp eax,1 //Сравниваем AValue с 1
jg @Biger1 //Если AValue>=1 то переходим на @Biger1
mov eax,1 //Иначе вернем 1
jmp @Exit // и Выдем
@Biger1:
push eax //Сохраняем eax иначе затрем его в дальнейшем
dec eax
call Factorial2 //Вызываем процедуру в eax уже лежит AValue-1
pop ecx //Вернем, то что положили в функции Factorial2
mul ecx //умножим на eax.
@Exit:
end;
Проверка:
- Код: Выделить всё
procedure TForm1.Button1Click(Sender: TObject);
begin
Caption:=IntToStr(Factorial(5));
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
Caption:=IntToStr(Factorial2(5));
end;
Дает верный результат….
Вопрос: Получается что вызов функции, по идее сопровождается простым вызовом оператора CALL. Но до этого мы как бы сами должны приготовить входные параметры ? Скажем у меня все просто нужно только положить число в EAX…(потому что Avalue должно лежать там)и просто вызвать функцию, после вызова, нужно знать где будет лежать результат… Для процедур которые используют параметры из стека (pascal вызов) мы сами должны будем приготовить стек…?
Но мы получается используем стек одной и той же функции… или это так и происходит, Не будет ли переполнения?...
Вопрос №2:
Вот если это так, например просто не понятно, что вложить в стек в этом случае...Различие стека в Delphi and FPC что за результ ($Result) там лежит….
в той теме было сказано что:
Kvasshtain писал(а):Но я считаю, что это банальный ЖУЧОК. Или точнее всего не жучок, а его кривое исправление . Т.е. они (разработчики) скорее всего чо то там сначала напутали, а потом исправили, но немножко криво. А может это какая то внутренняя особенность Лазарыча (ну типа что то вроде какая-то там дополнительная инфа по выполнению процедуры/функции в стек заносится, а чо за инфа и как она им используется, история типа умалчивает, или ищем не там где надо ). Вот мое ИМХО
Если это баг или неизвестно что туда положить, можно пока обойтись соглошением register. Но чтобы это работало хотябы при соглашении register, я должен разобраться с вопросом №1.
Спасибо за любые наводки по этому вопросу…