· Начало · Отвђтить · Статистика · Поиск · FAQ · Правила · Установки · Язык · Выход · WASM.RU · Noir.Ru ·

 WASM Phorum —› WASM.WIN32 —› Можно ли в C написать DlgProc чтоб код был с одним ret(максимум двумя)..

. 1 . 2 . 3 . >>

Посл.отвђт Сообщенiе


Дата: Окт 1, 2004 07:01:19

Можно ли в C написать DlgProc чтоб код был с одним ret(максимум двумя),
а то компилятор понапихал мне эпилог+ret заместо каждого return TRUE
или break или может какие ключи при компиляции заюзать, это же безобразие
какое-то.


Дата: Окт 1, 2004 07:39:55

Asterix
Покажи свой код, оповести о компиляторе, и об используемых ключах.


Дата: Окт 1, 2004 10:31:43

Я себе на днях поставил MS Visual C++ Toolkit , хочу посмотреть , что этот Си из себя представляет . Потом прочитал на uinc статью об уменьшении размера , получилось 1 Кб , нагуглил какой-то "naked" , чтоб прологи убрать , вроде получилось , теперь думаю как поубирать int3 (зачем-то понапихал компилер , выравнивает что-ли) и ещё можно ли сделать без заглушек , сразу call dword [ExitProcess] .

Компилю такой строкой "d:\c++\bin\cl /I d:\c++\include /Od test.c /link /SUBSYSTEM:WINDOWS /NOLOGO /RELEASE /LIBPATH:d:\c++\lib" , вот код :
//=====================================================
#pragma comment(linker,"/MERGE:.rdata=.text")
#pragma comment(linker,"/ALIGN:512 /SECTION:.text,EWRX")
#pragma comment(linker,"/ENTRY:start")
//=====================================================
#pragma comment(lib,"kernel32.lib")
//=====================================================
void  __stdcall ExitProcess(unsigned long);
//=====================================================
__declspec     (naked) start ()
{
        ExitProcess(0);
}
//=====================================================
з.ы. а си дворды не понимает ? Надо обязательно писать "typedef unsigned long dword;" ?


Дата: Окт 1, 2004 10:47:44

Понимает, только если в верхнем регистре: не dword, а DWORD. Кстати, это и будет typedef unsigned long DWORD :)

А насчет обрезания: я вот про naked не уловил сути. У меня все и без этого нормально работало.
#include <windows.h>
void EntryPoint()
{
  MessageBox(0,"zzz","dbg",MB_OK);
  ExitProcess(0);
}

Только настройки компилера и линкера не могу показать - они в VS2k3 через гуй делаются и все скрытно. Хотя, говорят, где-то есть и нормальный способ настраивания.. :)


Дата: Окт 1, 2004 11:10:59

__declspec (naked) start ()
{
ExitProcess(0);
}

а ты ret поставь в конце и int 3 не будет +) это же голая функция... тут всё надо самому делать +)

__declspec (naked) start ()
{
ExitProcess(0);
__asm{
ret
}
}


Дата: Окт 1, 2004 11:14:01

bogrus
теперь думаю как поубирать int3
Imho не надо. Однако если хочешь, то используй ключ /Os favor code space.

+ можно прагмить ключ /SUBSYSTEM

n0p
Только настройки компилера и линкера не могу показать
Новая студия не умеет делать makefile или его аналог?

Fallout
а ты ret поставь в конце и int 3
Заблуждаешься. Попробуй добавить еще подпрограмм. Между ними появятся CCh и не по одной. Это выравнивание и страховка от несанкционированного выполнения.


Дата: Окт 1, 2004 17:18:44

Мде +)... спасибо


Дата: Окт 1, 2004 18:46:48

q_q
> Покажи свой код, оповести о компиляторе, и об используемых ключах.

компилятор из MS VC++ 6.0
ключи CL=%CL% /nologo /GF /W4 /DNDEBUG /Ox /c
#include <windows.h>
#pragma comment(lib, "user32.lib")
#pragma comment(linker, "/opt:nowin98")
#include "resource.h"


BOOL CALLBACK DlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
 {
   switch(msg)
     {
        case WM_INITDIALOG:
              SendDlgItemMessage(hwnd, IDC_EDIT_1, EM_SETLIMITTEXT, 8, 0);
              return TRUE;

        case WM_CLOSE:
              EndDialog(hwnd, 0);
              return TRUE;

        case WM_COMMAND:
           switch(LOWORD(wParam))
             {
                case IDC_BUTTON_1:
                      return TRUE;

                case IDC_BUTTON_2:
                      MessageBox(hwnd, TEXT("text"), TEXT("About"), MB_OK);
                      return TRUE;

                case IDC_BUTTON_3:
                      SendMessage(hwnd, WM_CLOSE, 0, 0);
                      return TRUE;
             }
     }
	return FALSE;
 }

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpCmdLine, int nShowCmd)
 {
   return DialogBox(hInst, MAKEINTRESOURCE(IDD_DIALOG_1), 0, DlgProc);
 }


Дата: Окт 1, 2004 21:24:55

/Os рулит в данном случае


Дата: Окт 4, 2004 06:21:33

Asterix
компилятор понапихал мне эпилог+ret
Т.к. используется /Ox, то работу по оптимизации ты возлагаешь на компилятор, программа же изобилует return'ам, а не break'ами. Т.к. /Ox == /Ogityb1 + /Gs, а /Ot - оптимизация по скорости, то компилятор прав, ибо с точки зрения скорости, лучше ret, чем jmp + ret.


Дата: Окт 4, 2004 06:28:59

q_q
> Т.к. используется /Ox

А что нужно использовать, /O1 ??
Рекомендации ??

> программа же изобилует return'ам

Тоже самое будет если return'ы заменить на break'и..


Дата: Окт 4, 2004 07:29:47

Asterix
Тоже самое будет если return'ы заменить на break'и..
А /Ox убрал?

Рекомендации
Например, если убрать /Ox, то такой код обойдется без лишних ret'ов
BOOL CALLBACK DlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
  BOOL r = TRUE;

  switch(msg)
  {
  case WM_INITDIALOG:
    SendDlgItemMessage(hwnd, IDC_EDIT_1, EM_SETLIMITTEXT, 8, 0);
    break;
  case WM_CLOSE:
    EndDialog(hwnd, 0);
    break;
  case WM_COMMAND:
    switch(LOWORD(wParam))
    {
    case IDC_BUTTON_1:
      break;
    case IDC_BUTTON_2:
      MessageBox(hwnd, TEXT("text"), TEXT("About"), MB_OK);
      break;
    case IDC_BUTTON_3:
      SendMessage(hwnd, WM_CLOSE, 0, 0);
      break;
    }
  default:
    r = FALSE;
  }
  return r;
}
:-) если написать так, то можно оставить /Ox
BOOL CALLBACK DlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
  BOOL r = TRUE;

  switch(msg)
  {
  case WM_INITDIALOG:
    SendDlgItemMessage(hwnd, IDC_EDIT_1, EM_SETLIMITTEXT, 8, 0);
    goto l1;
  case WM_CLOSE:
    EndDialog(hwnd, 0);
    goto l1;
  case WM_COMMAND:
    switch(LOWORD(wParam))
    {
    case IDC_BUTTON_1:
      goto l1;
    case IDC_BUTTON_2:
      MessageBox(hwnd, TEXT("text"), TEXT("About"), MB_OK);
      goto l1;
    case IDC_BUTTON_3:
      SendMessage(hwnd, WM_CLOSE, 0, 0);
      goto l1;
    }
  }
  r = FALSE;
l1:
  return r;
}
Итого: если пишешь на Си, то прекращай думать по ассемблерщик, доверяй компилятору.

bogrus
сразу call dword [ExitProcess]
Ты стал "заложником" своего подхода (пытаешься обойтись без psdk), попробуй так
#include <windows.h>
#pragma comment(linker,"/MERGE:.rdata=.text")
#pragma comment(linker,"/ALIGN:512 /SECTION:.text,EWRX")
#pragma comment(linker,"/ENTRY:start")
#pragma comment(linker,"/SUBSYSTEM:WINDOWS")
#pragma comment(lib,"kernel32.lib")
__declspec(naked) start ()
{
  ExitProcess(0);
}
в результате см снимок из Olly


_1617374789__olly.gif


Дата: Окт 4, 2004 08:44:32

q_q
Ладно, с этим разобрались, хотя я не согласен с присваиванием переменной значения TRUE в начале, код получается некрасивый, я бы сделал по другому ;-)

Как мне вот здесь избавится от ret после ExitProcess(0)
догадываюсь что нужны какие-то трюки с __declspec
void start(void)
{
   hInstance = GetModuleHandle(NULL);
   DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_DIALOG_1), 0, (DLGPROC) DlgProc, 0);
   ExitProcess(0);
}


Дата: Окт 4, 2004 09:14:40

Asterix
я не согласен с присваиванием переменной значения TRUE в начале
Зря. Инициализировать переменные - хорошая практика.

Как мне вот здесь избавится от ret
bogrus уже показал __declspec(naked).


Дата: Окт 4, 2004 10:00:00

q_q
„Новая студия не умеет делать makefile или его аналог?“
Не знаю. Самостоятельно она его не делает, но может где-то глубоко в настройках и есть подобная фича.

. 1 . 2 . 3 . >>


Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.052