库函数代码ycio.cpp
#define YCNOH //该设置使编译器不调入默认的头文件
#include "ycos.h"
typedef char *va_list;
#define _ADDRESSOF(v) ( &reinterpret_cast<const char &>(v) )
#define _INTSIZEOF(n) ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )
#define va_start(ap,v) ( ap = (va_list)_ADDRESSOF(v) + _INTSIZEOF(v) )
#define va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )
#define va_end(ap) ( ap = (va_list)0 )
#define max(a,b) (((a) > (b)) ? (a) : (b))
#define min(a,b) (((a) < (b)) ? (a) : (b))
asm void ycio_write(const char *_Dest,int glen,int wrpos=-1)
{
mov eax, 0
lea ecx,[esp + 4]
int 80h
ret
}
asm int ycio_set_driver(byte *drvSrc,char *drvName)
{
mov eax, 1
mov edx,[esp + 8]
mov ecx,[esp + 4]
int 80h
ret
}
asm int ycio_get_driver(void *pObj,char *drvName)
{
mov eax, 2
mov edx,[esp + 8]
mov ecx,[esp + 4]
int 80h
ret
}
asm int ycio_create_process(byte *codeptr,char *cmdptr=nullptr,int glen=0)
{
mov eax, 3
lea edx,[esp + 8]
mov ecx,[esp + 4]
int 80h
ret
}
asm void ycio_delete_process(int pid=0)
{
mov eax, 4
mov ecx,[esp + 4]
int 80h
ret
}
asm int ycio_get_current_process()
{
mov eax, 5
int 80h
ret
}
asm void *malloc(unsigned int _Size)
{
mov eax, 6
mov ecx,[esp + 4]
int 80h
ret
}
asm void *realloc(void *_Memory,unsigned int _NewSize)
{
mov eax, 7
mov edx,[esp + 8]
mov ecx,[esp + 4]
int 80h
ret
}
void *calloc(unsigned int _Count,unsigned int _Size)
{
_Size *= _Count;
void *mptr = malloc(_Size);
if(mptr) memset(mptr,0,_Size);
return mptr;
}
asm void free(void *_Memory)
{
mov eax, 8
mov ecx,[esp + 4]
int 80h
ret
}
asm void ycio_cursor(int curpos)
{
mov eax, 9
mov ecx,[esp + 4]
int 80h
ret
}
asm void ycio_clear_screen(int bpos,int len)
{
mov eax, 10
mov edx,[esp + 8]
mov ecx,[esp + 4]
int 80h
ret
}
asm byte stdcall inb(unsigned short port)
{
mov dx,[esp + 4]
in al,dx
ret 4
}
asm void stdcall outb(unsigned short port, byte value)
{
mov dx,[esp + 4]
mov al,[esp + 8]
out dx,al
ret 8
}
void Sleep(int msVal)
{
for(int ii=0; ii<msVal; ii++);
}
long clock()
{
static long ms;
return ++ms;
}
asm void *stdcall memcpy(void *_Dst,const void *_Src,unsigned int _Size)
{
push edi
push esi
mov edi,[esp + 12] //_Dst
mov esi,[esp + 16] //_Source
mov ecx,[esp + 20] //_Size
mov eax, edi
push ecx
shr ecx, 2
rep movsd
pop ecx
and ecx,3
rep movsb
pop esi
pop edi
ret 12
}
asm int stdcall memcmp(void *_Dst,const void *_Src,unsigned int _Size)
{
push edi
push esi
mov edi,[esp + 12] //_Dst
mov esi,[esp + 16] //_Source
mov ecx,[esp + 20] //_Size
xor eax,eax
push ecx
shr ecx, 2
rep cmpsd
pop ecx
jnz mc_01
and ecx,3
rep cmpsb
jz mc_00
mc_01: inc eax
mc_00: pop esi
pop edi
ret 12
}
void *memmove(void *_Dst,const void *_Src,unsigned int _Size)
{
if(_Dst<=_Src || _Dst>=(char*)_Src+_Size) return memcpy(_Dst,_Src,_Size);
asm
{
std
mov edi, _Dst
mov eax, edi
mov esi, _Src
mov ecx, _Size
add edi,ecx
dec edi
add esi,ecx
dec esi
rep movsb
cld
}
}
asm void memset(void *_Dst,int _Val,unsigned int _Size)
{
push edi
mov edi, [esp + 8] //_Dst
mov al, [esp + 12] //_Val
mov ecx, [esp + 16] //_Size
rep stosb
pop edi
ret
}
asm char *stdcall strcpy(char *_Dest,const char *_Source)
{
push edi
push esi
mov edi,[esp + 12] //_Dest
mov esi,[esp + 16] //_Source
push edi
cp_0: lodsb
stosb
test al,al
jne cp_0
pop eax
pop esi
pop edi
ret 8
}
asm unsigned int stdcall strlen(const char *_Str)
{
push edi
mov edi,[esp + 8] //_Str
xor eax,eax
mov ecx,-1
repnz scasb
not ecx
dec ecx
mov eax,ecx
pop edi
ret 4
}
asm unsigned int stdcall wcslen(const wchar_t *_Str)
{
push edi
mov edi,[esp + 8] //_Str
xor eax,eax
mov ecx,-1
repne scasw
not ecx
dec ecx
mov eax,ecx
pop edi
ret 4
}
asm int strcmp(const char *_Str1, const char *_Str2)
{
push edi
push esi
mov edi,[esp + 12]
mov esi,[esp + 16]
scm_0: lodsb
scasb
jne scm_1
test al, al
jne scm_0
xor eax,eax
jmp scm_2
scm_1: mov eax,1
jl scm_2
neg eax
scm_2: pop esi
pop edi
ret
}
template<class T>
int getArgA(T *cmdbuf,T *argv[],int aLen)
{
if(!cmdbuf) return 0;
int argc = 0;
for(int ii=0; ; )
{
if(!cmdbuf[ii]) break;
for(; ; ii++)
{
if(!cmdbuf[ii]) break;
if(cmdbuf[ii] > ' ') break;
}
if(cmdbuf[ii] <= ' ') continue;
int mflag = cmdbuf[ii] == '"';
if(mflag) ii++;
if(argc >= aLen) break;
argv[argc++] = &cmdbuf[ii];
for(; ; ii++)
{
if(!cmdbuf[ii]) break;
if(mflag && cmdbuf[ii]=='"' || !mflag && cmdbuf[ii]<=' ')
{
int bb;
for(bb=ii-1; ; bb--) if(cmdbuf[bb] > ' ') break;
cmdbuf[++bb] = 0;
ii++;
break;
}
}
}
return argc;
}
template<class T>
int stdcall atoi(T *_Str)
{
while(*_Str && (unsigned T)*_Str<=' ') _Str++;
int flag=0,ii=0;
if(_Str[0] == '-') { _Str++; flag++; }
while(_Str[ii]>='0' && _Str[ii]<='9') ii++;
int bb=0, aa=1;
for(ii--; ii>=0; ii--)
{
bb += (_Str[ii] - '0') * aa;
aa *= 10;
}
return flag ? -bb : bb;
}
template<class T,class X>
int stdcall itoa(X _Val,T *_DstBuf,int _Radix=10,int dlen=0xffff,char chval='a')
{
T *desbuf = _DstBuf;
T *endbuf = desbuf + dlen -1;
if(_Radix >= 2)
{
if(_Radix==10 && _Val<0)
{
_Val = -_Val;
*desbuf++ = '-';
}
X bb = 1;
X aa = _Radix;
X ii = 1;
for(;;)
{
if(aa > (unsigned X)_Val) break;
ii++;
bb = aa; //printf("%d\n",0x7fffffff);
if((unsigned int64)aa * _Radix > (unsigned X)_Val) break;
aa *= _Radix;
if(aa < bb) break; //printf("%lu\n",0xffffffffffffffff);
}
for(; ii; ii--)
{
aa = (unsigned X)_Val / bb;
_Val -= aa * bb;
bb /= _Radix;
*desbuf++ = aa<10 ? aa + '0' : aa - 10 + chval;
if(desbuf >= endbuf)
{
desbuf = _DstBuf;
break;
}
}
}
*desbuf = 0;
return desbuf - _DstBuf;
}
template<class T>
int stdcall ycio_snprintf(T *_Dest,unsigned int _Count,T *_Format,
va_list _ArgList,int *pSrc=nullptr,T **pArgstr=nullptr)
{
int kk,aa,bb;
int ii = 0;
if(pArgstr)
{
ii = *pSrc;
*pArgstr = nullptr;
}
for(kk=0; kk<_Count; )
{
T uu = _Format[ii++];
if(uu != '%')
{
if(uu == '\0')
{
ii--;
break;
}
_Dest[kk++] = uu;
continue;
}
uu = _Format[ii++];
int jj = ii - 1;
int zero_flag = 0;
int head_pos = 0;
int tail_pos = 0;
if(uu>='0' && uu<='9' || uu=='.')
{
if(uu == '0')
{
zero_flag = 1;
uu = _Format[ii++];
}
while(uu>='0' && uu<='9') uu = _Format[ii++];
head_pos = atoi(&_Format[jj + zero_flag]);
if(uu == '.')
{
bb = ii;
uu = _Format[ii++];
while(uu>='0' && uu<='9') uu = _Format[ii++];
tail_pos = atoi(&_Format[bb]);
}
}
switch(uu)
{
default: _Dest[kk++] = uu; ii = jj + 1; break;
case 'X':
case 'x': bb = 16; goto it_p_001;
case 'o': bb = 8; goto it_p_001;
case 'b': bb = 2; goto it_p_001;
case 'u':
bb = 10; //printf("%u\n",0xffffffff);
bb = itoa(va_arg(_ArgList,unsigned),&_Dest[kk],bb,_Count-kk);
goto it_p_002;
case 'd':
bb = 10;
it_p_001:
bb = itoa(va_arg(_ArgList,int),&_Dest[kk],bb,
_Count-kk,uu=='X'?'A':'a');
it_p_002:
aa = max(head_pos,tail_pos);
if(bb && bb<aa && kk+aa<_Count)
{
memmove(&_Dest[kk+aa-bb], &_Dest[kk],bb*sizeof(T));
if(tail_pos)
{
if(head_pos > tail_pos)
{
head_pos -= tail_pos;
for(jj=0; jj<head_pos; jj++) _Dest[kk+jj] = ' ';
}
else jj = 0;
zero_flag = '0';
}
else
{
zero_flag = zero_flag ? '0' : ' ';
jj = 0;
}
aa -= bb;
for(; jj<aa; jj++) _Dest[kk+jj] = zero_flag;
bb += aa;
}
kk += bb;
if(!bb)
{
ii -= 2;
_Count = 0;
}
break;
case 'p':
bb = itoa(va_arg(_ArgList,int),&_Dest[kk],16,_Count-kk,'A');
if(bb == 0) goto it_p_002;
if(bb < 8)
{
memmove(&_Dest[kk+8-bb],&_Dest[kk],bb*sizeof(T));
bb = 8 - bb;
for(bb--; bb>=0; bb--) _Dest[kk+bb] = '0';
}
kk += 8;
break;
case 'l':
uu = _Format[ii];
if(uu == 'u')
{
ii++;
bb = itoa(va_arg(_ArgList,unsigned int64),
&_Dest[kk],10,_Count-kk);
if(!bb) ii--;
goto it_p_002;
}
if(uu=='x' || uu=='X')
{
ii++;
bb = 16;
}
else bb = 10;
bb = itoa(va_arg(_ArgList,int64),&_Dest[kk],bb,
_Count-kk,uu=='X'?'A':'a');
if(!bb && (uu=='x' || uu=='X')) ii--;
goto it_p_002;
case 's':
T *mptr = va_arg(_ArgList,T*);
if(sizeof(T) == 1)
{
if(!mptr) mptr = (T*)"(null)";
bb = strlen((char*)mptr);
}
else
{
if(!mptr) mptr = (T*)L"(null)";
bb = wcslen((wchar_t*)mptr);
}
if(kk + bb > _Count)
{
if(pArgstr)
{
*pArgstr = mptr;
_Count = 0;
break;
}
bb = _Count - kk;
}
if(tail_pos && bb>tail_pos) bb = tail_pos;
jj = bb;
head_pos -= bb;
if(head_pos < 0) head_pos = 0;
if(kk + head_pos + jj < _Count)
{
uu = zero_flag ? '0' : ' ';
for(; head_pos; head_pos--,kk++) _Dest[kk] = uu;
}
memcpy(&_Dest[kk],mptr,jj * sizeof(T));
kk += jj;
break;
}
}
if(pSrc) *pSrc = ii;
return kk;
}
template<class T>
int snprintf(T *_Dest,unsigned int _Count,const T *_Format, ...)
{
va_list argptr;
va_start(argptr, _Format);
int glen = ycio_snprintf(_Dest,_Count - 1, _Format, argptr);
_Dest[glen] = 0;
va_end(argptr);
return glen;
}
template<class T>
int sprintf(T *_Dest,const T *_Format, ...)
{
va_list argptr;
va_start(argptr, _Format);
int glen = ycio_snprintf(_Dest, 0x7fffffff, _Format, argptr);
_Dest[glen] = 0;
va_end(argptr);
return glen;
}
int printf(const char *_Format,...)
{
if(!_Format) _Format = "(null)";
va_list argptr;
va_start(argptr, _Format);
int ii,kk,glen;
for(glen = ii = 0; _Format[ii]; )
{
char tmp[128],*sptr;
kk = ycio_snprintf(tmp,sizeof(tmp),_Format,argptr,&ii,&sptr);
ycio_write(tmp,kk);
if(sptr) ycio_write(sptr,strlen(sptr));
glen += kk;
}
va_end(argptr);
return glen;
}
//内核屏幕打印函数
void printk(int vpos,int curpos,int bcolor,const char *_Format,...)
{
va_list argptr;
va_start(argptr, _Format);
char _Dest[128];
int glen = ycio_snprintf(_Dest,sizeof _Dest, _Format,argptr);
auto vidBuf = (byte*)(vpos * KERNEL_POS + 0xb8000);
for(int ii=0; ii<glen; ii++)
{
byte uu = _Dest[ii];
if(uu == '\t') curpos += 8 - (curpos % 8);
else if(uu == '\n') curpos += 80 - curpos % 80;
else
{
vidBuf[curpos*2] = uu;
vidBuf[curpos*2 +1] = bcolor;
curpos++;
}
}
va_end(argptr);
}
void code_copy(byte *runBuf,YCEXE *pYcexe,void *argc=0,
char *argv[]=0,
char *envp[]=0)
{
byte *exe_buf = (byte*)pYcexe + pYcexe->srcpos; //pYcexe->codelen: 代码总长度
BINPOS *pCodeb = (BINPOS*)exe_buf; //pCodeb->len: 函数总长度
memset(&runBuf[pCodeb->len], 0, pYcexe->codelen - pCodeb->len);//全局变量清零
byte *static_vbuf = &exe_buf[pYcexe->funpos]; //函数位置, 静态变量初始值位置
BINPOS *pCodeEnd = pCodeb + pYcexe->segnum;
for(; pCodeb<pCodeEnd; pCodeb++) //拷贝函数和所有静态变量初始值
{
memcpy(&runBuf[pCodeb->pos], static_vbuf, pCodeb->len);
static_vbuf += pCodeb->len;
}
int *repos = (int*)&exe_buf[pYcexe->addrpos]; //重定位的位置指针
int adjpos = (int)runBuf - pYcexe->org; //重定位增量
for(int kk=0; kk<pYcexe->addrnum; kk++) //设置switch表和全局变量实际地址
{
int bb = repos[kk];
if(bb >= 0) *(int*)&runBuf[bb] += adjpos; //处理 地址数=1 的情况
else
{
int addr_num = -bb * sizeof(int); //处理多个连续地址的情况
bb = repos[++kk];
addr_num += bb;
for(; bb<addr_num; bb+=sizeof(int)) *(int*)&runBuf[bb] += adjpos;
}
}
int *main_arg_pos = (int*)&exe_buf[pYcexe->argpos]; //形式参数位置指针
if(main_arg_pos[0]) *(int*)&runBuf[main_arg_pos[0]] = (int)argc; //形参0
if(main_arg_pos[1]) *(int*)&runBuf[main_arg_pos[1]] = (int)argv; //形参1
if(main_arg_pos[2]) *(int*)&runBuf[main_arg_pos[2]] = (int)envp; //形参2
}
template<class T>
void yc_add_link(T *pLink,T *&pHead)
{
if(!pHead) pHead = pLink->pLast = pLink;
pLink->pLast = pHead->pLast;
pLink->pNext = pHead;
pHead->pLast->pNext = pLink;
pHead->pLast = pLink;
}
template<class T>
void yc_delete_link(T *pLink,T *&pHead)
{
pLink->pLast->pNext = pLink->pNext;
pLink->pNext->pLast = pLink->pLast;
if(pHead == pLink)
{
pHead = pLink->pNext;
if(pHead == pLink) pHead = nullptr;
}
}
template<class T>
void yc_run_link(T *pHead,void (*pFunc)(T*))
{
if(!pHead) return;
T *pLink = pHead;
do{
pFunc(pLink);
pLink = pLink->pNext;
} while(pLink != pHead);
}
C/C++代码文件: ycio.cpp