一个最“小”程序的疑惑
在看<<程序员自我修养>>第4.6小结时,看到这样一个最“小”程序:
char* str = "Hello World\n";
void print()
{
asm("movl $13, %%edx\n\t"
"movl %0, %%ecx\n\t"
"movl $0, %%ebx\n\t"
"movl $4, %%eax\n\t"
"int $0x80"
::"r"(str):"edx","ecx","ebx");
}
void exit()
{
asm("movl $17, %ebx\n\t"
"movl $1, %eax\n\t"
"int $0x80\n\t");
}
void nomain()
{
print();
exit();
}
这是一个不需要任何C标准库即可在终端输出“Hello World”字样的程序,有助于了解程序链接过程的奥秘。
编译过程:
exit()函数中的汇编代码是看懂了,但print()中的汇编代码是我没有见过的形式,还请懂汇编的朋友帮忙解释下,谢谢!
Answers
C内嵌汇编的格式为
__asm__ __volatile__("Instruction List" : Output : Input : Clobber/Modify);
"r"(str) 为Input,对应Instruction List中的%0
可参考 http://www.embedu.org/Column/Column28.htm
系统调用通过0x80中断实现。其中eax为调用号,ebx,ecx,edx等通用寄存器来传递参数。
比如WRITE调用是往一个文件句柄写入数据,如果用C语言来描述它的原型就是:
int write(int filedesc, char *buffer, int size);
print函数中倒着看就是:
·WRITE调用的调用号为4, 则eax = 4
·filedesc表示被写入的文件句柄,使用ebx寄存器传递,我们这里是要往标准输出,它的文件句柄为0,即ebx = 0
·buffer表示要写入的缓冲区地址,使用ecx寄存器传递,我们这要输出字符串str,所以ecx = str.
·size表示要写入的字节数,使用edx寄存器传递,字符串“Hello world!\n”长度为13字节,所以edx = 13
来自 http://www.cnblogs.com/zhuyp1015/archive/2012/05/02/2479546.html