我们使用的平台是Linux系统,具体为CentOS⑹4位版。下面是第1个汇编程序的源码:
# 目的:退出Linux内核并返回1个简单的状态码
#
# 输入:无
#
# 输出:控制台上没有输出,可以用echo $?来查看状态码
#
# 变量:
# %eax 保存系统调用号
# %ebx 保存返回状态
#
.section .data
.section .text
.globl _start
_start:
movl $1,%eax #这是用于退出程序的Linux内核命令号(系统调用)
movl $8,%ebx #这是返回给操作系统的状态码
#改变这个数字,则返回到echo $?的值会不同
int $0x80 #将内核唤醒,以运行退出命令
Linux系统中,shell命令echo $?表示打印上1个命令履行的结果,该结果值的范围为0⑵55,1般将0作为命令成功履行的返回码。在该例子中我们使用的是8,而不是0,作为演示使用。
下面我们分析1下程序中代码的具体含义:
(1)以'#'号开头的为程序的注释,不会被编译或履行;
(2)以'.'开头的为汇编指令或伪操作,其实不会被翻译成机器指令;
.section .data 定义了程序的数据段的开始。数据段列出程序数据所需要的所有内存存储空间。
.section .text 定义了程序的文本段的开始。文本段是寄存程序指令的部份。
_start: 定义_start标签的值。
(3)程序指令:
movl $1,%eax
将数字1移入eax寄存器。$1和%eax称为指令movl的操作数。其中$1为寻址方式中的立即寻址,如果没有$符号,则是直接寻址;%eax称为寄存器,在x86系统中有以下几个通用寄存器:
%eax
%ebx
%ecx
%edx
%edi
%esi
有以下几个专用寄存器:
%ebp
%esp
%eip
%eflags
movl $8,%ebx
当程序履行结束时,程序退出的状态码保存在%ebx寄存器中,通过echo $?命令可以看到该值。
int $0x80