转自: http://www.cnblogs.com/orlion/p/5316519.html
原文链接:http://www.orlion.ga/989/
一、汇编程序的Hello world
x86 AT&T:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
然后汇编链接再执行:
这段汇编相当于:
1 2 3 4 5 6 7 8 9 |
|
.data段有一个标号msg,代表字符串“Hello,world!\n”的首地址,相当于C程序的一个全局变量。在汇编指示.ascii定义的字符串末尾没有隐含的‘\0’。汇编程序中的len代表一个常量,它的值由当前地址减去符号msg所代表的地址得到,换句话说就是字符串“Hello,world!\n”的长度。现在解释一下这行代码中的.,汇编器总是从前到后把汇编代码转换成目标文件,在这个过程中维护一个地址计数器,当处理到每个段的开头时把地址计数器置成0,然后每处理一条汇编指示或指令就把地址计数器增加相应的字节数,在汇编程序中用.可以取出当前地址计数器的值,是一个常量。
在_start中调了两个系统调用,第一个是write系统调用,第二个是以前讲过的_exit系统调用。在调write系统调用时,eax寄存器保存着write的系统调用号4,ebx、ecx、edx寄存器分别保存着write系统调用需要三个参数。ebx保存着文件描述符,进程中每个打开的文件都用一个编号来标识,成为文件描述符,文件描述符1表示标准输出,对应的C标准I/O库的stdout。ecx保存着输出缓冲区的首地址。edx保存着输出的字节数。write系统调用把从msg开始的len个字节写到标准输出。
C代码中的write函数是系统调用的包装函数,其内部实现就是把传进来的三个参数分别赋给ebx、ecx、edx寄存器,然后执行movl $4,%eax和int $0x80两指令。这个函数不可能完全用C代码写,因为任何C代码都不会编译生成int指令,所以这个函数有可能完全用汇编写的,也有可能是C用内联汇编写的,甚至是一个宏定义。_exite函数野史如此。
分类: 汇编