Tiny C run-time startup module for console applications

Started by Vortex, September 14, 2004, 11:31:10 AM

Previous topic - Next topic

Vortex

Hi friends,

Here, you can find a tiny C run-time startup module with asm command line parser for various C/C++ compilers ( including Pelle's compiler )

Pelle, could you add the attachment feature to the forum?

Thanks,

Vortex
Code it... That's all...


Vortex

Hi TBD,

Yes, you are right. Here is the solution:

Build.bat

call povars32.bat
polib /machine:ix86 /out:crtdll.lib /def:crtdll.def

\pellesc\bin\pocc /Zx /Ze /Zl /Os Test.c
\pellesc\bin\polink /SUBSYSTEM:CONSOLE /OUT:Test.exe ..\startc.obj Test.obj ..\ParseCmdLine.obj kernel32.lib crtdll.lib


crtdll.def

LIBRARY crtdll
EXPORTS
printf

...which normally is enough for this small example.

If you would like to get the zip file,y ou can send me a PM with your e.mail address.
Code it... That's all...

TBD

thanks Vortex.

I created the lib myself using podump.exe /exports, removing the extra, adding LIBRARY crtdll, EXPORTS.

Vortex

Code it... That's all...

Vortex

Here is the startup module for GUI applications.

The code in C:

#include <windows.h>

extern UINT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow);

HMODULE hInstance;

void WINAPI WinMainCRTStartup()
{
hInstance=GetModuleHandle(NULL);
ExitProcess(WinMain(hInstance,NULL,GetCommandLine(),SW_SHOWDEFAULT));
}


The equivalent code in asm with some manual optimizations, wcrt0.asm :

[cpu 486]
[global _WinMainCRTStartup]
[section .text]
[function _WinMainCRTStartup]
_WinMainCRTStartup:
push dword (0)
call dword [(__imp__GetModuleHandleA@4)]
mov dword [(_hInstance)],eax
call dword [(__imp__GetCommandLineA@0)]
push dword 10
push dword eax
push dword (0)
push dword [(_hInstance)]
call _WinMain@16
push dword eax
call dword [(__imp__ExitProcess@4)]
..?X_WinMainCRTStartup:
[section .bss]
[global _hInstance]
[common _hInstance 4]
[extern _WinMain@16]
[extern __imp__GetCommandLineA@0]
[extern __imp__GetModuleHandleA@4]
[extern __imp__ExitProcess@4]


No need to use an external assembler to generate the object code.
An example of building a GUI based application:

call "povars32.bat"
pocc wcrt0.asm
pocc /Ze /Zl /Os Window.c
polink /SUBSYSTEM:WINDOWS /OUT:Window.exe wcrt0.obj Window.obj kernel32.lib user32.lib


The attachment contains a demo using this tiny C run-time startup code, the size of the final executable - a simple window is only 2048 bytes.

Click here to download the attachment.
Code it... That's all...

Vortex

Bug fixed : The lpCmdLine parameter should point the first command line parameter not the filename.


[cpu 486]
[global _WinMainCRTStartup]
[section .text]
[function _WinMainCRTStartup]
_WinMainCRTStartup:
push dword (0)
call dword [(__imp__GetModuleHandleA@4)]
mov dword [(_hInstance)],eax
call dword [(__imp__GetCommandLineA@0)]
dec eax
@100:
inc eax
mov cl,byte [eax]
or cl,cl
jz @102
cmp cl,32
jne @100
dec eax
@101:
inc eax
mov cl,byte [eax]
cmp cl,32
je @101
@102:
push dword 10
push dword eax
push dword (0)
push dword [(_hInstance)]
call _WinMain@16
push dword eax
call dword [(__imp__ExitProcess@4)]
..?X_WinMainCRTStartup:
[section .bss]
[global _hInstance]
[common _hInstance 4]
[extern _WinMain@16]
[extern __imp__GetCommandLineA@0]
[extern __imp__GetModuleHandleA@4]
[extern __imp__ExitProcess@4]


New attachment uploaded at the top.
Code it... That's all...

Jibz

Nice work vortex :).

I am not quite sure, but I think that code might fail if the filename or path at the start of the string returned by GetCommandLine contains spaces?

Vortex

Hi Jibz,

GetCommandLine removes those leading spaces, so there is no problem.
Code it... That's all...

Jibz

What I meant was that if the filename of the executable itself contains spaces, then GetCommandLine will return something like:
"C:\Foo\With Space.exe" arg1 arg2
where the filename with path is quoted because it contains a space.

Try in your example to show the contents of lpCmdLine in a messagebox, and then rename the executable to something with a space.

Vortex

Hi Jibz,

Thanks for pointing me the right direction.

Here is the code:

[cpu 486]
[global _WinMainCRTStartup]
[section .text]

[function _WinMainCRTStartup]

_WinMainCRTStartup:
push dword (0)
call dword [(__imp__GetModuleHandleA@4)]
mov dword [(_hInstance)],eax
call dword [(__imp__GetCommandLineA@0)]
cmp byte [eax],34 ;check for leading quote
jne @102
@100: ;look for the second quote
inc eax
mov cl,byte [eax]
or cl,cl
jz @104
cmp cl,34
jne @100
jmp @103 ;look for space chars
@101:
inc eax
@102: ;skip file name
mov cl,byte [eax]
or cl,cl
jz @104
cmp cl,32
jne @101
dec eax
@103: ;skip space chars
inc eax
mov cl,byte [eax]
cmp cl,32
je @103
@104:
push dword 10
push dword eax
push dword (0)
push dword [(_hInstance)]
call _WinMain@16
push dword eax
call dword [(__imp__ExitProcess@4)]

..?X_WinMainCRTStartup:

[section .bss]
[global _hInstance]
[common _hInstance 4]
[extern _WinMain@16]
[extern __imp__GetCommandLineA@0]
[extern __imp__GetModuleHandleA@4]
[extern __imp__ExitProcess@4]
Code it... That's all...

TimoVJL

Project file for WCRT0:

#
# PROJECT FILE generated by "Pelles C for Windows, version 2.80".
# NOTE! Manual changes of this file is done at your own risk.
#

POC_PROJECT_VERSION = 1.00#
POC_PROJECT_TYPE = 2#
POC_PROJECT_PATH = .#
POC_PROJECT_ARGUMENTS = #
POC_PROJECT_WORKPATH = #
POC_PROJECT_EXECUTOR = #
CC = pocc.exe#
AS = pocc.exe#
AR = polib.exe#
CCFLAGS = #
ASFLAGS = #
ARFLAGS = #

.SILENT:  

#
# Build WCRT0.LIB.
#
"$(POC_PROJECT_PATH)\WCRT0.LIB": \
 "$(POC_PROJECT_PATH)\output\wcrt0.OBJ"
 $(AR) $(ARFLAGS) -out:"$@" $**

#
# Build wcrt0.OBJ.
#
"$(POC_PROJECT_PATH)\output\wcrt0.OBJ": \
 "$(POC_PROJECT_PATH)\wcrt0.asm"  
 $(AS) $(ASFLAGS) -Fo"$@" "$!"


Then you can use it in source file with

#pragma nodefaultlib
#pragma comment(lib, "wcrt0.lib")
May the source be with you

Vortex

Code it... That's all...

Vortex

Here is another example using Pelle's C run-time DLL pocrt.dll

#define WIN32_LEAN_AND_MEAN
#define IDC_EDIT 4001

#include <stdio.h>
#include <windows.h>

HINSTANCE hInstance;
FILE *file;
char buffer[75];
char k;
char i=0;

BOOL CALLBACK DlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
  switch(msg)
   {
       case WM_CLOSE:
EndDialog(hwnd,0);
       break;
       case WM_INITDIALOG:
file=fopen("Text.txt","r");

while ( k=fgetc(file)) {
if (k==EOF) {
buffer[i]=0;
break;
}

if (k==10) {
buffer[i]=13;
++i;
}

buffer[i]=k;
++i;
}
fclose(file);
SetDlgItemText(hwnd,(int)IDC_EDIT,buffer);
      break;
default:
           return FALSE;
   }
   return TRUE;

}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow)
{
LPCTSTR DlgName="MyDialog";
hInstance=GetModuleHandle(0);
return(DialogBoxParam(hInstance,DlgName,0,DlgProc,0));
}
[/code]
Code it... That's all...

Vortex

Hi friends,

Here is the latest release of my C startup code very easy to use, now this time the sample projects both GUI and console are supported with ppj files. The startup codes are assembler with Masm.
Code it... That's all...