1 2 3 4 5 6 7 | void nomain() { asm("movl $42, %ebx \n\t" "movl $1, %eax \n\t" "int $0x80 \n\t"); } |
程序中使用了EXIT系统调用,Linux中是通过0×80号中断实现的,寄存器ebx表示进程退出码,比如我们平时的main程序中的return的数值会返回系统库,由系统库将该数值传递给EXIT系统调用。这样父进程就能接受到子进程的退出码,例如在bash中环境变量$?就保存了上一个命令(即子进程)的退出码。寄存器eax用来保存系统调用的调用号,例如EXIT系统调用的调用号是1,write系统调用号为4。因此这个小程序的功能就是直接返回至父进程。
这里面没有用到C库,也没有main函数,为了把这个程序编译成可执行文件,需要指定程序的入口。编译指令:
1 2 3 4 5 6 7 8 9 10 | $ gcc -c nomain.c $ ld -e nomain nomain.o -o nomain $ ./nomain $ echo $? 42 $ ls -l nomain -rwxr-xr-x 1 ivan ivan 618 2009-09-02 22:11 nomain $ strip nomain $ ls -l nomain -rwxr-xr-x 1 ivan ivan 356 2009-09-02 22:15 nomain |
解释一下,ld是linux下的一个链接器,-e选项用来指定程序的入口。编译后可执行文件的大小为618字节(一个动态链接的HelloWorld需要9KB,静态链接将近600K),strip命令可以”剥去”可执行文件中的调试信息,可进一步减小文件的大小,另外在链接时通过其他选项还可以将可执行文件中保存的编译器和系统版本信息也一并去掉……
此程序虽已经很小,没有调用任何C库,但还是脱离不了操作系统而独立运行。
你好!除了代码,此处没有多少原创之物,皆为本人搜集、整理、总结之记录与心得,欢迎转载分享!转载时请尽量注明出处,将不胜感激。祝你健康、快乐!
jmp $