Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Помогите найти Ошибку!!!!!!!!!!!!!!!!!!!!!!


4ert ©   (2006-12-29 03:48:00) 

Здравтсвуйте Уважаемые Мастера!!!!!!!!!!!!!!!!!!!
Помогите найти ошибку в следующем коде:


unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, StdCtrls;

type
 TForm1 = class(TForm)
   Button1: TButton;
   procedure Button1Click(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
 end;

var
 Form1: TForm1;
const
 MaxParam = 32;
implementation

{$R *.dfm}

function f2(a:pointer):integer; assembler;
asm
 push edi
 push esi
 mov ecx,MaxParam*4
 sub esp,ecx
 mov edi,esp
 lea esi,[ebp+8]
 rep movsd
 lea edi,[esp+MaxParam*4]
 call eax
 mov esp,edi
 pop edi
 pop esi
end;

function f1(hWnd: HWND; lpText, lpCaption: PAnsiChar; uType: UINT): Integer; stdcall;
var
 a: pointer;
begin
 a:=@MessageBoxA;
 f2(a);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
f1(0,'TEST','HEAD',MB_OK);
end;

end.


В результате нажатия на Button1 я, таки, вижу MessageBox с кнопкой Ok заголовком HEAD и текстом TEST, но при нажатии на кнопку OK ловлю следующее сообщение:


Project Project1.exe raised exception class EAccessViolation with message 'Access Violation at address 001703CA read of address 001703CA'. Process stopped.


Честно говоря, assemblerna`я вставка не моя, и я почти не знаком с этим без сомнений замечательным языком, поэтому найти ошибку  просто не в состоянии, вот и прошу, нет, молю!!!!!!!!!!!
Помочь мне исправить этот код....

Заранее спасибо!!!!!


evvcom   (2006-12-29 09:35:00) [1]

Такие вещи отладчиком проверяют. Это гораздо проще. Но на первый взгляд, по-моему, так:
mov ecx,MaxParam*4
sub esp,ecx

резервируешь под 32 параметра 32*4 байта
mov edi,esp
lea esi,[ebp+8]
rep movsd

Во-первых, перед movsd немешало бы удостовериться, что копирование будет идти в нужном направлении (по-моему это cld и std);
Во-вторых, ты копируешь ecx раз по 4 байта, т.е. 32*4*4, тем самым затирая в стеке больше, чем там зарезервировал своим sub esp,ecx. Т.е. надо либо shr ecx,2, либо movsb, но лучше первое.
Отладчиком пройдись.


Elen   (2006-12-29 09:28:00) [2]


> 4ert

Вот как делает отладчик делфи :

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TForm1 = class(TForm)
  Button1: TButton;
  procedure Button1Click(Sender: TObject);
private
  { Private declarations }
public
  { Public declarations }
end;

var
Form1: TForm1;
const
MaxParam = 32;
implementation

{$R *.dfm}

function f1(hWnd: HWND; lpText, lpCaption: PAnsiChar; uType: UINT): Integer; stdcall;
var mb:pointer;
begin
mb:=@messageboxA;
asm
mov eax,[ebp+$14]
push eax
mov eax,[ebp+$10]
push eax
mov eax,[ebp+$0c]
push eax
mov eax,[ebp+$08]
push eax
call mb
end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
f1(0,'TEST','HEAD',MB_OK);
end;

end.


а ты помоему с функциями переборщил.


Elen   (2006-12-29 09:16:00) [3]


> 4ert

А чего б не посмотреть как это делфийский дебугер делает. и кстати, зачем тебе это именно функцией описывать?, помоему ты из стека по окончании выполнения не весь мусор выбрал.


Котик Б   (2006-12-29 09:10:00) [4]

Вот одного не пойму... чего ты у нас спрашиваешь ? Спроси у автора кода...


4ert   (2006-12-29 04:00:00) [5]

сорри функция выглядет так:


function f2(a:pointer):integer; assembler;
asm
 push edi
 push esi
 mov ecx,MaxParam*4
 sub esp,ecx
 mov edi,esp
 lea esi,[ebp+8]
 rep movsd
 lea edi,[esp+MaxParam*4]
 call eax
 mov esp,edi
 pop esi
 pop edi
end;


Наверх

Титульная страница Поиск, карта сайта Написать письмо