Различие стека в Delphi and FPC
Добавлено: 21.02.2011 17:28:52
Прочитал книгу «Использование ассемблера в Дельфи» автор: Гуйдо Гайбелс.
Но не совсем разобрался с мелочами, а именно со стэком. Если быть точным в различии стэков между Delphi and Free Pascal.
Везде пишут, что обращаться нужно по имения переменной а не через указания адреса типа [EBP-4], да это верно, но когда разбираешь пример по полочкам нужно проделать хотя бы раз именно так через [EBP-4] и хорошо представить себе как выглядит стэк.
Вот что я тестил:
Тестируем:
Должны вернуть цифру 3. потому что стэк выглядит вот так:
В данном случае EBP=ESP и указывают они на Previous EBP, т.е если [EBP+8] заменить на [ESP+8], ничего не изменится. Для Delphi стэк выглядит именно так, в Free pascal. Нужно писать [ESP+12] чтобы вернуть 3, т.е в стэк записали что то еще, и он стал выглядеть так:
Я правильно понял, но что там лежит? Почему такие различия?
Если переписать процедуру так, чтобы добавилась локальная переменная:
То стэк будет выглядеть так:
Если провести тест, то вернем 255 и в Delphi и в FP.
Если хотим вернуть число 3 (Value3) то в Delphi число 3 лежит по адресу [ESP+12], в FP по адресу [ESP+16], если работать через EBP. То для Delphi и FP, 3 лежит по адресу [EBP+8]. Вывод, в FP опять что то поместили между EBP и верхушкой стэка (в данном случаем переменной М).
Объясните если не трудно. Просто очень хочется разобраться, но так чтобы было понимание и в Delphi и в Free Pascal.
Но не совсем разобрался с мелочами, а именно со стэком. Если быть точным в различии стэков между Delphi and Free Pascal.
Везде пишут, что обращаться нужно по имения переменной а не через указания адреса типа [EBP-4], да это верно, но когда разбираешь пример по полочкам нужно проделать хотя бы раз именно так через [EBP-4] и хорошо представить себе как выглядит стэк.
Вот что я тестил:
- Код: Выделить всё
function Test3Param2(Value1,Value2,Value3:Integer):Integer; pascal;
asm
mov EAX, [EBP+8]
end;
Тестируем:
- Код: Выделить всё
procedure TForm1.Button1Click(Sender: TObject);
begin
Caption:=IntToStr(Test3Param2(1,2,3));
end;
Должны вернуть цифру 3. потому что стэк выглядит вот так:
- Код: Выделить всё
Value1
Value2
Value3
Return Address //Адрес возврата
Previous EBP // Предыдущее значение EBP
В данном случае EBP=ESP и указывают они на Previous EBP, т.е если [EBP+8] заменить на [ESP+8], ничего не изменится. Для Delphi стэк выглядит именно так, в Free pascal. Нужно писать [ESP+12] чтобы вернуть 3, т.е в стэк записали что то еще, и он стал выглядеть так:
- Код: Выделить всё
Value1
Value2
Value3
Return Address //Адрес возврата
Previous EBP // Предыдущее значение EBP (EBP указывает на этот адрес)
Что то еще //STP указывают сюда..
Я правильно понял, но что там лежит? Почему такие различия?
Если переписать процедуру так, чтобы добавилась локальная переменная:
- Код: Выделить всё
function Test3Param2(Value1,Value2,Value3:Integer):Integer; pascal;
var M:Integer;
asm
mov M, $FF // M:=255;
mov EAX, [ESP]
end;
То стэк будет выглядеть так:
- Код: Выделить всё
Value1
Value2
Value3
Return Address //Адрес возврата
Previous EBP // Предыдущее значение EBP (EBP указывает на этот адрес)
M // ESP будет указывать на ячейку памяти в которой записана переменная M
Если провести тест, то вернем 255 и в Delphi и в FP.
Если хотим вернуть число 3 (Value3) то в Delphi число 3 лежит по адресу [ESP+12], в FP по адресу [ESP+16], если работать через EBP. То для Delphi и FP, 3 лежит по адресу [EBP+8]. Вывод, в FP опять что то поместили между EBP и верхушкой стэка (в данном случаем переменной М).
Объясните если не трудно. Просто очень хочется разобраться, но так чтобы было понимание и в Delphi и в Free Pascal.