Tiny C run-time startup module for console applications

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

Previous topic - Next topic

Gerome

Hi Vortex,

Very nice additions :)
This can be eventually added to the PellesC distro ?
It can be interesting to have several ways of making Executables :)

BTW, do you have the equivalent tiny CRTs for a DLL and a Static LIB please ?

Thanks again for this wonderful job !

Quote from: "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.

Vortex

Hi Gerome,

Thanks for your kind words. The linker extracts and links only the necessary member functions from static libraries, these ones doesn't  require any startup code.

I will post an example for DLLs.
Code it... That's all...

Vortex

Hi Gerome,

The tricks to create small DLLs are again avoiding using static C run-time libraries, plus setting the entry point of the DLL to:

DllMain@12


The project I posted is an example of an autotyper. The application launches notepad.exe and characters of a message starts to appear one by one on the notepad! :)
The autotyping function is called from a DLL sized only 3072 bytes.
Code it... That's all...

Vortex

Hi friends,

Here is another C run-time startup module coded with GoAsm
Code it... That's all...

Vortex

Here is a new version of the library coded with POASM
Code it... That's all...

lvckyluke

vortex, the console startup code didn't check for 'tab'..  it failed to read correct argv[] when running the program with batch file that exist tab as commandline separator.

i make fixup like this:


; POASM
.586
.model flat,c
option casemap:none

WINBASEAPI_GetCommandLineA typedef proto stdcall
externdef stdcall _imp__GetCommandLineA@0: ptr WINBASEAPI_GetCommandLineA
GetCommandLine equ <_imp__GetCommandLineA@0>

WINBASEAPI_ExitProcess typedef proto stdcall :DWORD
externdef stdcall _imp__ExitProcess@4: ptr WINBASEAPI_ExitProcess
ExitProcess equ <_imp__ExitProcess@4>

main proto c :DWORD,:VARARG

.data?
_p__args db 144 dup(?) ; 32 for argv[x8], 128 for buffer

.code

_setargv proc uses esi edi
invoke GetCommandLine
mov esi,eax
mov edx,offset _p__args
push edx
lea edi,[edx+32]
xor ecx,ecx
mov ah,32
@@:
lodsb
test al,al
jz @5
cmp al,9
jz @b
cmp al,ah
jz @b
@0:
mov [edx],edi
add edx,4
inc ecx
jmp @2
@1:
lodsb
cmp al,ah
jz @3
cmp al,9
jz @3
@2:
cmp al,34
jnz @4
xor ah,32
jmp @1
@3:
mov al,0
@4:
stosb
test al,al
jnz @1
dec esi
jmp @b
@5:
mov eax,ecx ; argc
pop ecx        ; argv[1]
ret
_setargv endp

public mainCRTStartup
mainCRTStartup proc
push ebp
mov ebp,esp
invoke _setargv
invoke main,eax,ecx ; argc,argv
invoke ExitProcess,eax
mainCRTStartup endp
end


Vortex

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

Vortex

New version of the tiny C run-time startup library ( Wcrt0_7.zip ) :

The NULL terminator character of the last command-line argument was not copied to the destination buffer by the module crt0cons. This bug is fixed now.

ParseCmdLineParam.zip : Command-line parser for Jwasm \ Masm \ Poasm console applications
Code it... That's all...

TimoVJL

#23
Thanks Vortex.

Here is similar code converted to C :
//#define WIN32_LEAN_AND_MEAN
//#include <windows.h>

#ifndef _WINDOWS_H
void _stdcall ExitProcess(unsigned int);
char __stdcall *GetCommandLineA(void);
#define GetCommandLine GetCommandLineA
int __stdcall lstrlenA(char *);
#define lstrlen lstrlenA
int __cdecl wsprintfA(char *, char *, ...);
#define wsprintf wsprintfA
#define DWORD unsigned long
int __stdcall WriteFile(void *, char *, DWORD, DWORD*, void*);
void * __stdcall GetStdHandle(DWORD);
#define STD_OUTPUT_HANDLE -11
#endif

#pragma comment(lib, "kernel32")
#pragma comment(lib, "user32")

char szCmdLine[1024];

int ParseCmdLine(char *pCmdLine)
{
char *pPos, *pP2, cSp, cTab;
int iArgs;

pPos = GetCommandLine();
pP2 = pCmdLine;
cSp = 32;
cTab = 9;
iArgs = 0;
do { // scan commandline
if (*pPos == ' ' || *pPos == '\t') // strip whitespaces off
continue;
iArgs++;
do { // loop cmdline
if (!*pPos) {
*pP2 = *pPos; // store 0 too
break;
}
if (*pPos == cSp || *pPos == cTab) { // if not quoted it is separator
break; // end of parameter
}
if (*pPos == '"') { // quote ?
cSp ^= 32;
cTab ^= 9;
continue;
}
*pP2++ = *pPos; // store char
} while (*pPos++);
*pP2++ = 0;
} while (*pPos++);
return iArgs;
}

int __cdecl mainCRTStartup(void)
{
int nLen, nIdx, nCnt;
DWORD dwWrite;
char *pPos, szTmp[1024];

nCnt = ParseCmdLine(szCmdLine);
pPos = szCmdLine;
nIdx = 0;
do {
nLen = wsprintf(szTmp, "par %d = %s\n", nIdx++, pPos);
WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), szTmp, nLen, &dwWrite, 0);
pPos += lstrlen(pPos) + 1;
} while(--nCnt);

ExitProcess(0);
return 0;
}
May the source be with you