Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 23.10.2012, 20:52   #11
eval
Подтвердите свой е-майл
 
Регистрация: 29.08.2012
Сообщений: 4,011
По умолчанию

это, если правильно помню не stdcall, а fastcall
eval вне форума Ответить с цитированием
Старый 23.10.2012, 21:45   #12
xoodoo
Форумчанин
 
Регистрация: 11.04.2012
Сообщений: 212
По умолчанию

То есть соглашение - Pascal fastcall.

В 32-битной среде оно подразумевает передачу первых не более чем трех аргументов через РОН eax, edx, ecx слева направо в порядке декларации.

А ты мало того что игнорируешь требования fastcall-соглашения, так еше и нарушаешь условия задания, в котором с твоих же слов заявлено требование по stdcall-соглашению.
xoodoo вне форума Ответить с цитированием
Старый 24.10.2012, 08:29   #13
Biohazard
Пользователь
 
Регистрация: 23.02.2009
Сообщений: 78
По умолчанию

всем спасибо) вопрос закрыт, помогли на другом форуме)

конечный результат функции

Код:
function SetFunction(dll, adress, param: String): DWORD;
var
  hdll: HMODULE;
  LastError: DWORD;
  proc: Pointer;
  Params: array of DWORD;
  Strings: array of String;
  PrmCount, StrCount, p: Integer;
  p1, p2: String;
  //param = integer:8;boolean:true; ...
begin
  hdll := LoadLibrary(Pointer(dll));
  if hdll = 0 then
  begin
    LastError := GetLastError;
    RaiseErrorFmt('Ïðè çàãðóçêå áèáëèîòåêè "%s" âîçíèêëà îøèáêà ¹%d: "%s"',
      [dll, LastError, SysErrorMessage(LastError)]);
  end;

  try
    proc := GetProcAddress(hdll, Pointer(adress));
    if not Assigned(proc) then
      RaiseErrorFmt('Â áèáëèîòåêå "%s" îòñóòñòâóåò ïðîöåäóðà "%s"', [dll, adress]);

    PrmCount := 0;
    StrCount := 0;

    while param <> '' do
    begin
      p := Pos(':', param);
      if p = 0 then RaiseErrorFmt('Îæèäàëñÿ ñèìâîë ":" â ñòðîêå "%s"', [param]);
      p1 := LowerCase(Copy(param, 1, p - 1));
      Delete(param, 1, p);

      p := Pos(';', param);
      if p = 0 then RaiseErrorFmt('Îæèäàëñÿ ñèìâîë ";" â ñòðîêå "%s"', [param]);
      p2 := Copy(param, 1, p - 1);
      Delete(param, 1, p);

      if Length(Params) = PrmCount then SetLength(Params, PrmCount + 10);

      if p1 = 'integer' then
      begin
        Params[PrmCount] := StrToInt(p2);
      end else
      if p1 = 'boolean' then
      begin
        Params[PrmCount] := StrToInt(p2);
      end else
      if p1 = 'pchar' then
      begin // Çäåñü ñòðîêè íèãäå íå ñîõðàíÿëèñü, ïîýòîìó óêàçàòåëè íà íèõ òåðÿëè àêòóàëüíîñòü
        if Length(Strings) = StrCount then SetLength(Strings, StrCount + 10);
        Strings[StrCount] := p2;
        Params[PrmCount] := DWORD(Strings[StrCount]);
        Inc(StrCount);
      end else
      begin
        RaiseErrorFmt('Íåïîääåðæèâàåìûé òèï "%s"', [p1]);
      end;
      Inc(PrmCount);
    end;

    asm
      PUSH ESI
      PUSH EDI
      MOV  ESI, Params
      MOV  ECX, PrmCount
      NEG  ECX
      LEA  ESP, [ESP + ECX * 4] // Çäåñü áûëà îøèáî÷íàÿ èíñòðóêöèÿ lea esp, [esp - ecx * 4]
      NEG  ECX
      MOV  EDI, ESP
      CLD
      REP  MOVSD
      MOV  EAX, proc
      CALL EAX
      MOV  Result, EAX // Ñîõðàíÿåì ðåçóëüòàò ðàáîòû âûçâàííîé ôóíêöèè
      POP  EDI
      POP  ESI
    end;
  finally
    FreeLibrary(hdll);
  end;
end;

// Ïðèìåð âûçîâà (â èñõîäíîì âàðèàíòå çäåñü áûëà îøèáêà):
procedure TForm1.Button1Click(Sender: TObject);
begin
  SetFunction('shell32.dll', 'ShellExecuteA', 'Integer:0;PChar:;PChar:calc.exe;PChar:;PChar:;Integer:0;');
end;
by poli-smen - он помог)
Biohazard вне форума Ответить с цитированием
Старый 24.10.2012, 09:52   #14
xoodoo
Форумчанин
 
Регистрация: 11.04.2012
Сообщений: 212
По умолчанию

Код:
      MOV  Result, EAX // Бессмысленная строка, ибо Result и есть EAX
      POP  EDI
      POP  ESI
    end;
  finally
    FreeLibrary(hdll); // этот вызов затрет Result
  end;
xoodoo вне форума Ответить с цитированием
Старый 24.10.2012, 12:31   #15
Biohazard
Пользователь
 
Регистрация: 23.02.2009
Сообщений: 78
По умолчанию

Цитата:
Сообщение от xoodoo Посмотреть сообщение
Код:
      MOV  Result, EAX // Бессмысленная строка, ибо Result и есть EAX
      POP  EDI
      POP  ESI
    end;
  finally
    FreeLibrary(hdll); // этот вызов затрет Result
  end;
я в ассеме не очень хорошо, но может еах имеется ввиду от используемой функции библиотечной, а результ от нашей, кстати, реально сделать чтобы учитывалось var const и out, как в ассеме это осуществить тут?
Biohazard вне форума Ответить с цитированием
Старый 24.10.2012, 13:20   #16
xoodoo
Форумчанин
 
Регистрация: 11.04.2012
Сообщений: 212
По умолчанию

Цитата:
а результ от нашей
"Наша" функция имеет соглашение fastcall, в котором, точно так же как и в stdcall, возвращает результат через eax.
Посему компилятор при генерации машкода строчки
Код:
mov Result, eax
заменит Result на eax
В результате машинструкция этой строчки будет
mov eax, eax
которая и является совершенно бестолковой и лишней.

Цитата:
реально сделать чтобы учитывалось var const и out
const и out можно вообще не рассматривать - это фичи, специфичные исключительно для компайл-тайм.

var имеет смысл рассматривать только при условии что клиентское описание параметров вызова позволяет описать и переменные, ссылки на которые требуется передать соотв. var-параметрами.
xoodoo вне форума Ответить с цитированием
Старый 24.10.2012, 13:42   #17
Biohazard
Пользователь
 
Регистрация: 23.02.2009
Сообщений: 78
По умолчанию

Цитата:
Сообщение от xoodoo Посмотреть сообщение
const и out можно вообще не рассматривать - это фичи, специфичные исключительно для компайл-тайм.

var имеет смысл рассматривать только при условии что клиентское описание параметров вызова позволяет описать и переменные, ссылки на которые требуется передать соотв. var-параметрами.
вот тут в статье помоему какраз про то как это сделать, но я не знаю ассем и даже в таком виде не знаю как это использовать

Передача параметров по значению говорится о const?

Процедуре передается собственно значение параметра. При этом фактически значение параметра копируется, и процедура использует его копию, так что модификация исходного параметра оказывается невозможной. Этот механизм применяется для передачи небольших параметров, таких как байты или слова.

Например, если параметры передаются в регистрах:
Код:
        mov        ax,word ptr value   ; сделать копию значения
        call       procedure           ; вызвать процедуру
Передача параметров по ссылке напоминает out

Процедуре передается не значение переменной, а ее адрес, по которому процедура должна сама прочитать значение параметра. Этот механизм удобен для передачи больших массивов данных и для тех случаев, когда процедура должна модифицировать параметры, хотя он и медленнее из-за того, что процедура будет выполнять дополнительные действия для получения значений параметров.
Код:
        mov        ax,offset value
        call       procedure
Передача параметров по возвращаемому значению//похоже на var

Этот механизм объединяет передачу по значению и по ссылке. Процедуре передают адрес переменной, а процедура делает локальную копию параметра, затем работает с ней, а в конце записывает локальную копию обратно по переданному адресу. Этот метод эффективнее обычной передачи параметров по ссылке в тех случаях, когда процедура должна обращаться к параметру достаточно большое число раз, например, если используется передача параметров в глобальной переменной:
Код:
        mov        global_variable,offset value
        call       procedure
        [...]
procedure proc near
        mov        dx,global_variable
        mov        ax,word ptr [dx]
       (команды,  работающие с АХ в цикле десятки тысяч раз)
        mov        word ptr [dx],ax
procedure endp
из этой статьи

Последний раз редактировалось Biohazard; 24.10.2012 в 13:53.
Biohazard вне форума Ответить с цитированием
Старый 24.10.2012, 16:41   #18
xoodoo
Форумчанин
 
Регистрация: 11.04.2012
Сообщений: 212
По умолчанию

Цитата:
даже в таком виде не знаю как это использовать
Да ни как ты это не сможешь использовать при конкретно тех условиях, какие фигурируют в задании.
xoodoo вне форума Ответить с цитированием
Старый 24.10.2012, 17:09   #19
Biohazard
Пользователь
 
Регистрация: 23.02.2009
Сообщений: 78
По умолчанию

не думаю что задача нерешаема, думаю что просто она нам с вами не по зубам(
Biohazard вне форума Ответить с цитированием
Старый 24.10.2012, 17:29   #20
xoodoo
Форумчанин
 
Регистрация: 11.04.2012
Сообщений: 212
По умолчанию

Тебе она точно не по зубам.
Что касается меня, то задание дано не мне.
Но если бы оно таки было дано мне, то первое чтобы я сделал - ткнул препода носом в заведомую противоречивость его требований, ибо ни о каких передачах параметров по ссылкам не может вообще идти речи при том примитивном описании аргументов.
xoodoo вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Загрузка компонент из DLL Hottabych Компоненты Delphi 0 13.02.2011 16:18
[DLL] Загрузка и выгрузка dll в/из чужого процесса Человек_Борща Win Api 4 28.02.2010 17:47
Загрузка dll Колючка* Общие вопросы Delphi 3 12.02.2010 19:45
загрузка .dll blackstersl Общие вопросы Delphi 1 29.04.2009 21:53
Загрузка DLL Hollander Общие вопросы Delphi 3 21.05.2007 20:19