#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <memory>
#include <string>
#include <cstdarg>
#include <map>
#include <vector>
#include <windows.h>
using namespace std;
#define CCT_AALIGN 0x4
#define CCT_SALIGN 0x8
#define CCT_E_SUCCESS 0xF0000000
#define CCT_E_UNKNOWNTYPE 0xF0000001
#define CCT_E_WRONGNATYPE 0xF0000002
#define CCT_E_MULTRETUAN 0xF0000004
#define CCT_RT 0x10000000
#define CCT_UNK 0x1000
#define CCT_INT 0x1001
#define CCT_32 0x1002
#define CCT_DOUBLE 0x1004
#define CCT_64 0x1008
#define CCT_NA 0x1010
//----------------------------------------------------------------------------
struct cct {
unsigned t;
unsigned rn;
unsigned bc;
unsigned mc;
char* b;
cct* n;
cct():t(CCT_UNK), rn(0), bc(0), mc(0), b(0), n(0){};
void newbuf(unsigned size) { if (b) free(b); b=(char*)malloc(size); }
virtual ~cct() { if (b) free(b); }
}; // end of cct
#define cct_astype(a,t) (t&)(*(t*)a.b)
//----------------------------------------------------------------------------
#define ASM_RET_SPACE(rtc,rta) \
_asm mov eax, dword ptr[rtc]\
_asm cmp eax, 4\
_asm jle rsD\
_asm sub esp, eax\
_asm mov dword ptr[rta], esp\
_asm rsD: \
#define ASM_RET_ADDR(rta) \
_asm push dword ptr[rta]\
#define ASM_SAVERETURN(v_buf, rtc) \
_asm mov edx, dword ptr[v_buf]\
_asm mov ecx, dword ptr[rtc]\
_asm cmp ecx, 4\
_asm jg rtL\
_asm mov dword ptr[edx], eax\
_asm jmp srD\
_asm rtL: cmp ecx, 0\
_asm jz srD\
_asm mov esi, dword ptr[eax]\
_asm mov dword ptr[edx], esi\
_asm add eax, 4\
_asm add edx, 4\
_asm sub ecx, 4\
_asm jmp rtL\
_asm srD: \
#define ASM_MOVE_32P(v_buf) \
_asm sub esp, 4\
_asm mov edx, dword ptr[v_buf]\
_asm mov eax, dword ptr[edx]\
_asm mov dword ptr[esp], eax\
#define ASM_MOVE_64P(v_buf) \
_asm sub esp, 8\
_asm mov ecx, esp\
_asm mov edx, dword ptr[v_buf]\
_asm mov eax, dword ptr[edx]\
_asm mov dword ptr[ecx], eax\
_asm add ecx, 4\
_asm mov edx, dword ptr[v_buf]\
_asm mov eax, dword ptr[edx+04h]\
_asm mov dword ptr[ecx], eax\
#define ASM_MOVE_naP(v_buf, v_bc, v_mc) \
_asm mov ecx, dword ptr[v_bc]\
_asm inc ecx\
_asm mov eax, 4\
_asm mul ecx\
_asm mov edx, dword ptr[v_buf]\
_asm sub esp, eax\
_asm mov esi, esp\
_asm dec ecx\
_asm napL: cmp ecx, 0\
_asm jz TAIL\
_asm mov eax, dword ptr[edx]\
_asm mov dword ptr[esi], eax\
_asm add edx, 04h\
_asm add esi, 04h\
_asm dec ecx\
_asm jmp napL\
_asm TAIL: mov ecx, dword ptr[v_mc]\
_asm cmp ecx, 3\
_asm jnz M2\
_asm mov al, byte ptr[edx]\
_asm mov byte ptr[esi],al\
_asm inc edx\
_asm inc esi\
_asm mov ax, word ptr[edx]\
_asm mov word ptr[esi],ax\
_asm jmp naPD\
_asm M2: cmp ecx, 2\
_asm jnz M1\
_asm mov ax, word ptr[edx]\
_asm mov word ptr[esi],ax\
_asm jmp naPD\
_asm M1: cmp ecx, 1\
_asm jnz naPD\
_asm mov al, byte ptr[edx]\
_asm mov byte ptr[esi],al\
_asm naPD: \
#define ASM_STDCALL_CALL(v_pfunc) \
_asm call v_pfunc\
void cc_call(cct* a, void* p) {
int err=0;
int rtc=0;
int rta=0;
cct *r=0;
int v_eax=0;
char* v_rb=0;
while (a&&!err) {
char* b=a->b;
int v_bc=a->bc; int v_mc=a->mc;
if (a->t&CCT_RT) {
if (rtc) { err=CCT_E_MULTRETUAN; }
else {
switch(a->t&~CCT_RT) {
case CCT_INT:
case CCT_32: rtc=sizeof(int); break;
case CCT_DOUBLE:
case CCT_64: rtc=sizeof(double); break;
case CCT_NA: {
if (a->bc+a->mc) {rtc=(a->bc+1); rtc<<=2; }
else { err=CCT_E_WRONGNATYPE; }
} break;
default: err=CCT_E_UNKNOWNTYPE;
}
if (rtc) {
r=a;
r->newbuf(rtc);
r->t=CCT_RT;
v_rb=r->b;
ASM_RET_SPACE(rtc, rta);
}
}
} else {
switch(a->t) {
case CCT_INT:
case CCT_32: {
ASM_MOVE_32P(b);
} break;
case CCT_DOUBLE:
case CCT_64: {
ASM_MOVE_64P(b);
} break;
case CCT_NA: {
ASM_MOVE_naP(b, v_bc, v_mc);
} break;
default: err=CCT_E_UNKNOWNTYPE;
}
}
a=a->n;
}
if (!err) {
if (rtc) {
ASM_RET_ADDR(rta);
}
ASM_STDCALL_CALL(p);
if (rtc) {
ASM_SAVERETURN(v_rb, rtc);
}
} else { printf("err:\t%d\n", err); }
}
//----------------------------------------------------------------------------
struct Large1{ char c; short s; int i; };
struct Large2{ char c; double d; };
struct Large3{ char b[5]; };
struct Large4{ char b[4]; };
struct Large5{ char b[6]; };
struct Large6{ char b[13]; };
int aa(int a, Large1 l) { unsigned mass=0x10000000; return a+l.c+l.s+l.i; }
double bb(double a, char b) { return a+b; }
void __cdecl cc(double a) { printf("cc:\t%f\n", a); }
void __stdcall dd(Large2 a) { printf("dd:\t%f\n", a.d); }
void __stdcall ee(Large3 a) { printf("ee:\t%d\n", sizeof(Large3)); }
void __stdcall ff(short s, char c) { printf("ff:\t%d,%c\n", s, c); }
void __stdcall gg(const char* s) { printf("gg:\t%s\n", s); }
void __stdcall hh(void (__stdcall*p)(const char* s)) { printf("hh:\t0x%x\n", p); }
void __stdcall ii(int i) { printf("ii:\t%d\n", i); }
void __stdcall jj(double d) { printf("jj:\t%f\n", d); }
void __stdcall kk(Large4 l) { printf("kk:\t%s\n", l.b); }
void __stdcall ll(Large4 l) { printf("ll:\t%s\n", l.b); }
Large6 __stdcall mm(Large6 l) {
return l;
/*
mov eax,dword ptr [ebp+8]
mov ecx,dword ptr [l]
mov dword ptr [eax],ecx
mov edx,dword ptr [ebp+10h]
mov dword ptr [eax+4],edx
mov ecx,dword ptr [ebp+14h]
mov dword ptr [eax+8],ecx
mov dl,byte ptr [ebp+18h]
mov byte ptr [eax+0Ch],dl
mov eax,dword ptr [ebp+8]
*/
}
Large6 __stdcall nn(Large6 l) {
int len=strlen(l.b);
for(int i=0;i<len;++i) { l.b[i]+=1; }
printf("nn:\t%s\n", l.b);
return l;
}
int __stdcall oo() { printf("oo:\t99\n"); return 99; }
//----------------------------------------------------------------------------
int main() {
{/* int gap=0x2468;
Large1 l; l.c=0x40; l.s=0x24; l.i=0x68;
unsigned mass=0x00000;
gap=aa(0x123, l);
double a=1.0;
char b=0x20;
a=bb(a,b);
*/}
{ double d=12.34;
_asm {
fld qword ptr[d]
sub esp, 8
fstp qword ptr[esp]
call [cc]
add esp, 8 // __cdecl
}
}
{
Large2 l2; l2.c=0x68; l2.d=56.78;
/*
sub esp,10h
mov eax,esp
mov ecx,dword ptr [l]
mov dword ptr [eax],ecx
mov edx,dword ptr [ebp-24h]
mov dword ptr [eax+4],edx
mov ecx,dword ptr [ebp-20h]
mov dword ptr [eax+8],ecx
mov edx,dword ptr [ebp-1Ch]
mov dword ptr [eax+0Ch],edx
call dd
*/ dd(l2);
}
{
Large3 l3;
/*
sub esp,8
mov eax,esp
mov ecx,dword ptr [l3]
mov dword ptr [eax],ecx
mov dl,byte ptr [ebp-34h]
mov byte ptr [eax+4],dl
call ee
*/ ee(l3);
}
{
short s=0x45; char c='A';
/*
movzx eax,byte ptr [c]
push eax
movzx ecx,word ptr [s]
push ecx
call ff
*/ ff(s, c);
}
{
const char* s="abc";
/*
mov eax,dword ptr [ebp-5Ch]
push eax
call gg
*/ gg(s);
}
{
/*
push offset gg
call hh
*/ hh(&gg);
}
/*
_asm {
push 999
call dword ptr[Sleep]
} */
{
cct p;
p.newbuf(sizeof(int));
p.t=CCT_INT;
cct_astype(p, int)=13579;
cc_call(&p, &ii);
}
{
cct p;
p.newbuf(sizeof(double));
p.t=CCT_DOUBLE;
cct_astype(p,double)=5678.9;
cc_call(&p, &jj);
}
{
cct p;
p.newbuf(sizeof(Large4));
p.t=CCT_32;
strcpy(p.b, "abc");
cc_call(&p, &kk);
}
{
cct p;
p.newbuf(sizeof(Large5));
p.t=CCT_NA;
p.bc=1;
p.mc=2;
strcpy(p.b, "abcde");
//cc_call(&p, &ll);
}
{
Large6 l;
strcpy(l.b, "god");
Large6 r=mm(l);
printf("mm:\t%s\n", r.b);
}
{
cct pr; pr.t=CCT_NA+CCT_RT;
pr.bc=3; pr.mc=1;
cct p;
p.newbuf(sizeof(Large6));
p.t=CCT_NA; p.bc=3; p.mc=1;
strcpy(p.b, "abcdefg");
pr.n=&p;
cc_call(&pr, &nn);
printf("nn:\t%s\n", pr.b);
}
{
cct pr2; pr2.t=CCT_INT+CCT_RT;
cc_call(&pr2, &oo);
printf("oo:\t%d\n", *pr2.b+12);
}
printf("END!\n");
return 0;
}
//----------------------------------------------------------------------------
//
#define CCT_ROUND(s,round) ((s)+(round)-1)&~((round)-1)
int cct_align(int PackAlign, const vector<int>& List) {
int result=0;
/*
int count=List.size();
if (count > 0) {
int i=1;
int max_size=0;
int min_size=0;
for (auto n : List) {
max_size=max(max_size,n);
min_size=min(PackAlign,n);
if (i) { i=0; result=n; printf("-%d\n", result); }
else {
result=CCT_ROUND(result+n, min_size);
printf("*%d\n", result);
}
}
min_size=min(PackAlign,max_size);
result=CCT_ROUND(result, min_size);
printf("+%d\n", result);
}
*/
return result;
}