用户的命令由command执行,首先command把程序加入内存,然后设置CPU的CS:IP指向程序的第一条指令(也就是程序入口,在C++中就是main()函数),从而使程序得以运行.程序结束后,返回到command中,CPU继续运行command.注意在返回的时候要有一个返回值,这样才能安全退出程序(注意我用的是退出一词),之后各寄存器会有恢复动作,如果没有返回值,虽然表面上看程序也正常结束了,但实际上它并没有退出,各寄存器并没有恢复,如CS:IP 还是指向程序尾部,如果得到CS:IP,那么可以让程序继续执行下去,但是所执行的程序已经不是你的代码所在的那段内存空间了,它在执行其它内存中的程序.
你听谁说应用程序加载是直接进入main()函数的?你以为编译器那么笨你不写return函数,函数执行完后就不会退栈返回?你写一个void function(void)函数然后让main调用,该函数不写return你看能不能返回到main中。建议你去买本谭老的c语言入门教材从头学起。
不知你有没有念过本科,学没学一点操作系统原理的课,知不知道什么是进程。你喜欢谈shell我就跟你讨论下shell,下面是个简单的shell的实现:
程序代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <unistd.h>
#define MAXLINE 256
int main(void)
{
char buf[MAXLINE];
pid_t pid;
int status;
printf(\"%%\"); //pintf prompt
while(fgets(buf,MAXLINE,stdin)!=NULL){
if(buf[strlen(buf)-1]=='\n')
buf[strlen(buf)-1]==0; //replace newline with null
if((pid=fork())<0){
printf(\"fork error\n\");
exit(1);
}
else if(pid==0){ //child process
execlp(buf,buf,(char*)0);
printf(\"couldn't execute: %s\",buf);
exit(127);
}
if((pid=waitpid(pid,&status,0))<0){ //child process
printf(\"waitpid error\");
exit(1);
}
printf(\"%%\");
}
}
fork函数创建子进程,子进程调用exec函数簇的一个(这里是execlp)执行另一个程序,执行到exec时该进程用新的程序替换旧的程序,新的程序再从main开始执行,exec的作用就是用新的程序替换当前进程的正文,数据,堆和栈。
如果你想在windows系统中实现,做一个command.com或cmd.exe,只需要把fork换成CreateProcess,execlp对应的是ShellExecute,不过这里还有一些区别,这里的CreateProcess功能强一点不用再用ShellExecute,如果不另开进程也可以只用ShellExecute(不过这样就不是shell了)。一个程序在shell中可以选择后台运行,这样在打开子进程后可以继续解释命令不用等待,你的什么不能返回是扯淡。不要拿些个指令指针CS:IP来混弄人,或许你学了点8086实模式16位汇编,win32asm不知道你有没有学过。
在C++中,如果是void main()的话,理论上说,应该不会正常结束,当然,这完全是我的猜测,
你的帖子中全是这种“理论上”,“可能”,“猜测”的词,不知道你不会去查一下资料搞清楚?
俺刚来,也没有什么NB的技术,只是见不得别人糊弄初学者。
[此贴子已经被作者于2007-10-1 17:44:23编辑过]