|
|
| Посл.отвђт | Сообщен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;
}:-) если написать так, то можно оставить /OxBOOL 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 или его аналог? Не знаю. Самостоятельно она его не делает, но может где-то глубоко в настройках и есть подобная фича. |
|
Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.052 |