汇编程序--退出

时间:2022-04-18 00:55:29

作为第一个汇编程序,本程序除了退出以外,并没有执行其他的功能。

#目的: 退出并向Linux内核返回一个状态码的简单程序


#输入: 无


#输出: 返回一个状态码.在运行程序后可通过输入echo $?来读取状态码


#变量:
# %eax保存系统调用号
# %ebx保存返回状态
#
.section .data


.section .text


.globl _start


_start:
movl $1, %eax  #这是用于退出程序的Linux内核命令号(系统调用)


movl $40, %ebx  #这是我们将返回给操作系统的状态码
      #改变这个数字,则返回到echo $?的值会不同


int $0x80      #这将唤醒内核,以运行退出命令

在编辑器中输入以上代码之后,我们需要做的第一步就是汇编程序,汇编的过程就是将汇编语言转换成机器指令。汇编程序可以输入以下命令:

as exit.s -o exit.o

其中as是运行汇编程序的命令,exit.s是保存以上代码的源文件,-o exit.o是告诉汇编程序将输出到目标文件exit.o中,exit.o是用机器语言写成的代码。目标文件的内容通常不完全放到一个地方,许多大的程序有许多个源文件,将每个源文件转化成一个目标文件,形成许多个目标文件。这是就需要用链接器程序把多个目标文件合二为一,并向其中添加信息,使内核知道该如何加载和运行该程序,链接程序的命令为:

ld exit.o -o exit

其中,ld是运行链接器的命令,exit.o 是目标文件,-o exit指示链接器输出新程序到名为exit的文件。对于文件的扩展名来说,在Liunx或者Unix中,文件的扩展名是可有可无的,Unix的可执行文件通常是没有扩展名的。注意:对源文件做任何修改之后,为在程序中实现这些更改,必须重新汇编和链接程序。接下来要运行程序,可以输入如下命令:

./exit

其中,./用来告诉计算机,改程序并非位于常用目录下,而是当前目录下,.指系统当前目录。

如果你在运行完改程序之后,立即输入:

echo $?

屏幕上就会出现一个40,因为每个程序退出的时候都会向Linux返回一个退出状态码,告诉系统一切运行是否正常,可以通过echo $?来查看状态码。

下面开始介绍本程序的代码的含义

在本程序中有很多以#开头的行,这表示这一行是注释,用来解释说明程序。

.section .data
在汇编程序中,任何以小数点(.)开始的指令都不会被直接翻译成机器指令,这些针对汇编程序本身的指令,由于是由汇编程序处理,实际上并不会由计算机运行,因此被称为汇编指令或伪操作。本程序中.section指令将程序分成几个部分。.section  .data命令是数据段的开始,数据段中要列出本程序所需要的内存的存储空间。有该程序没有使用任何的数据,所以可以不需要该指令,但是为了使程序具有完整性,我们保留了该指令。

int $0x80 

.section .text
表示文本段开始,文本段用来存放程序的指令。

.globl _start
.globl表示汇编程序不应该在汇编之后废弃这个符号,因为链接器需要它。_start 是一个特殊的符号,总是用.globl来标记,它将在汇编或者链接过程中被其他的内容替换。符号一般用来程序或者数据的位置,所以你可以用名字来代替内存地址。

_start:
用来定义_start的标签的值。标签是一个符号,后面跟一个冒号。标签定义一个符号的值。当汇编程序对程序进行汇编的时候,必须为每个数值或者每条指令分配地址。标签告诉汇编程序以该符号的值作为下一条指令或者下一条数据的位置。

movl $1, %eax 
将数字1移入寄存器%eax,其中1前面的$表示要用立即寻址方式寻址。之所以将1移入寄存器%eax中,是因为我们需要进行系统调用exit。当我们进行系统调用的时候,必须将系统调用号加载到%eax中。

大多数的指令都有两个操作数,第一个操作数是源操作数,第二个操作数是目的操作数。在这种情况下,源操作数根本不会改变,结果存放到目的操作数中。

movl $40, %ebx 
操作系统除了要知道要进行哪个调用,还需要知道其他的各种信息,在进行exit调用的时候,操作系统需要将状态码加载到%ebx,这个值将被返回到操作系统。

Linux只需要在系统调用之前将某些参数加载到某些寄存器中,通常我们需要将系统调用号加载到%eax中,而对于其他的寄存器,每个系统调用有不同的要求。

int $0x80
int代表中断,0x80是用到的中断号。中断会中断正常的程序流,把控制权从我们的手中转移到操作系统,和执行一个系统调用,当完成一个系统调用之后,控制权再次回到程序中。本程序中要求Linux退出程序,因此程序不会再获得控制权。