Linux汇编教程02:编写第一个汇编程序

学习一门语言,最好的方式就是在运用中学习,那么在这一章节中,我们开始编写我们的第一个汇编程序。当然作为第一个程序,其实十分的简单,但可以给大家一个基本的轮廓,了解汇编大概是这样的。

我们这个程序实际上没什么作用,只是简单的推出而已。下面就是程序的范例

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

# 输入: 无

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

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

.section .data

.section .text

.globl _start

_start:

movl $1, %eax # 这是退出程序的Linux内核命令号

movl $0, %ebx # 返回的状态码

int $0x80 # 唤醒内核以执行退出命令

完成上面的源代码,进行汇编

32位机器:as exit.s -o exit.o

64位机器:as –32 exit.s -o exit.o

在命令中,as是汇编命令,exit.s 是源文件 -o 是重命名,让我们生成的文件叫exit.o,exit.o就是目标文件。在Linux为 .o 后缀,在Windows下为 .obj 后缀。

目标文件是用机器语言写的代码,接下来我们需要使用链接器进行链接。

32位机器:ld exit.o -o exit

64位机器:ld -melf_i386 exit.o -o exitls

ld就是链接器命令

要运行exit的话,可以使用 ./exit 命令。当你输入命令,点完回车之后,光标只是进入了下一行,毕竟我们这个程序只是退出而已。

不过但你运行完程序马上输入 echo $? 会发现屏幕上会出现一个0。这个0就是返回的状态码

接下来我们开始分析每个部分。

以#号开头的为注释

.section .data

在汇编中,任何以小数点开始的指令都不会被翻译为机器指令,这些针对汇编本身的指令有汇编程序处理,实际上并不会在计算机上运行,这些指令是汇编指令。.section 指令是把程序分成几个区块。

.section .data 命令是数据段的开始,数据段中要列出程序数据所需的内存空间。我们这个程序太过简单,所以没有数据,这个命令其实也可以不写。保留这个指令只是为了保留程序的结构完整,知道程序的基本框架。

.section .text 是文本段,也就是代码区啦,这里容纳程序指令

.globl  _start

这一条指令中 _start 是一个符号,帮助人理解而已,在汇编和链接过程中会被替换。一般来说,符号用来标记程序或数据的位置,所以通过符号而不是内存中的位置编号来指代他们。

.globl 表示汇编程序不应该在汇编之后把这个符号舍弃,因为连接器还需要它。_start 是一个特殊符号,总是使用 .globl 来标记,应为这个标记是程序的入口。

_start:

定义_start标签的值。当汇编程序对程序进行汇编的时候,必须为每一个数值和指令分配地址。标签告诉汇编程序以符号的值作为下一条指令或下一个数据元素的位置。这样,如果数据或指令的实际物理地址更改了,也不需要重新引用,应为符号会自动获取新值。

下面开始就是真正的计算机指令了。

movl $1, %eax

当程序运行时该指令将数值1移入%eax寄存器中。 movl 指令有两个操作数,一个是源操作数,另一个是目的操作数。根据上一讲,$1 是立即寻址方式,在指令中就包含需要的数字。这里1是源操作数,%eax是目的操作数。操作数的类型一般是数字,内存位置引用或寄存器。而 movl 的作用是从内存位置复制一个字大小的数据到另一个位置。(PS:movb的话操作数是字节)。1移入%eax是让系统调用exit。进行系统调用时,必须把系统调用号加载到%eax中,有些系统调用还需要其他寄存器也包含有值。

x86处理器上的通用寄存器

  • %eax
  • %ebx
  • %ecx
  • %edx
  • %edi
  • %esi

除了通用寄存器,还有几个专用寄存器

  • %ebp
  • %esp
  • %eip
  • %eflags

引申一点,在x86处理器的通用寄存器都以e开头,e 是 extern 的意思,即扩展。主要是因为以前的x86处理器是16位的,后来才变为32位,为了向前兼容,保留了旧名,在前面加上了e作为32位的扩展寄存器。而在64位采用的是r前缀,比如说%rax就是64位的%eax寄存器。大家可以试着把前面的代码改一下,汇编,链接,运行。

在进行系统调用的情况下,操作系统还需要将状态吗加载到%ebx,这个值后背返回给系统

movl $0, %ebx

这句命令和上面类似,就不解释了。

int $0x80

int 表示中断,0x80是中断号。还有,0x80是16进制数,不是10进制的80。

原文地址:https://www.cnblogs.com/guochaoxxl/p/10468710.html

时间: 2024-10-12 11:48:49

Linux汇编教程02:编写第一个汇编程序的相关文章

Linux汇编教程01: 基本知识

在我们开始学习Linux汇编之前,需要简单的了解一下计算机的体系结构.我们不需要特别深入的了解,理解了一些基本概念对与我们理解程序会很有帮助.现在计算机的结构体系都是采用冯诺依曼体系结构的基础上发展过来的.而冯诺依曼的体系有两个主要组成部分:CPU和内存.而我们的汇编语言和这两个部分十分密切. 1.1 内存结构 内存的结构就像一排连续的房子,或者是一种矩阵.每个空间的大小是固定的,且每一个存储单元都有自己的地址或者编号.房子的地址是门牌号,而内存的每个单元都有自己的地址. 计算机的内存有数以万计

Linux汇编教程03:大小比较操作

我们在上一讲中,简单了解了汇编程序大概的样子.接下来我们来了解一下,汇编程序的大小比较操作.所以我们以编写寻找一堆数中的最大值作为学习的载体. 在编写程序之前,先要分析我们的目的,在得出解决方案. 目的:在一堆数中找到最大的数 思路:要实现这个目的,首先,我们一定要对数据进行索引,每一次比较,两个数应该分别占用一个寄存器,得到最大值,所以,我们有一个寄存器一定是存放最大值的.一开始没有最大值,我们不妨设第一个数为最大值,后面一次索引大小比较.得出最大值.索引中还会用到循环结构. 解决方案——代码

Linux汇编教程04:寻址方式

这一节,我们主要来讨论寻址方式,这一点十分重要. 我们上一节有稍微提了一下,内存地址引用的通用格式: 地址或偏移(%基址寄存器, %索引寄存器, 比例因子 ) 结果地址 = 地址或偏移 + %基址寄存器 + 比例因子 + %索引寄存器 地址或偏移和比例因子必须是常数,剩下的那两个必须是寄存器,在缺省的情况下,都用0来代替. 立即寻址方式 直接将值加载到目地位置中 movl $221, %eax</p> 1 直接寻址方式 通过使用地址或偏移来实现 movl ADDRESS, %eax</p

迅为4412开发板Linux驱动教程——编写简单应用调用驱动

Linux驱动教程:http://pan.baidu.com/s/1c0hljUS 编写简单应用调用驱动--头文件 ? 打印头文件 – include <stdio.h>调用打印函数printf ? 应用中调用文件需要的头文件 – #include <sys/types.h>基本系统数据类型.系统的基本数据类型在32 编译 环境中保持为32 位值,并会在64 编译环境中增长为64 位值. – #include <sys/stat.h>系统调用函数头文件.可以调用普通文件

Linux makefile 教程 很具体,且易懂

近期在学习Linux下的C编程,买了一本叫<Linux环境下的C编程指南>读到makefile就越看越迷糊,可能是我的理解能不行. 于是google到了下面这篇文章.通俗易懂.然后把它贴出来,方便学习. 后记,看完发现这篇文章和<Linux环境下的C编程指南>的makefile一章所讲述的惊人的类似,仅仅是这篇文章从一个实例切入,在有些地方比較好理解.能让人看懂就是好文章. 跟我一起写 Makefile陈皓 (CSDN)概述--什么是makefile?也许非常多Winodws的程序

很详细、很移动的Linux makefile教程:介绍,总述,书写规则,书写命令,使用变量,使用条件推断,使用函数,Make 的运行,隐含规则 使用make更新函数库文件 后序

很详细.很移动的Linux makefile 教程 内容如下: Makefile 介绍 Makefile 总述 书写规则 书写命令 使用变量 使用条件推断 使用函数 make 的运行 隐含规则 使用make更新函数库文件 后序 近期在学习Linux下的C编程,买了一本叫<Linux环境下的C编程指南>读到makefile就越看越迷糊,可能是我的理解能不行. 于是google到了以下这篇文章.通俗易懂.然后把它贴出来,方便学习. 后记,看完发现这篇文章和<Linux环境下的C编程指南>

32位汇编第二讲,编写窗口程序,加载资源,响应消息,以及调用C库函数

32位汇编第二讲,编写窗口程序,加载资源,响应消息,以及调用C库函数 (如果想看所有代码,请下载课堂资料,里面有所有代码,这里会讲解怎么生成一个窗口程序) 一丶32位汇编编写Windows窗口程序 首先我们知道32位汇编是可以调用Windows API的,那么今天我们就调用windowsAPI来写一个窗口程序 如果你有windows开发知识,那么就很理解了,如果没有,那么跟着我写,跟着步骤去写,那么也可以写出来 首先我们要编写一个窗口程序(使用SDKAPI编写)有几个步骤 1.设计窗口类 2.注

Linux汇编实例讲解(一)

我们使用的平台是Linux系统,具体为CentOS-64位版.下面是第一个汇编程序的源码: # 目的:退出Linux内核并返回一个简单的状态码 # # 输入:无 # # 输出:控制台上没有输出,可以用echo $?来查看状态码 # # 变量: # %eax 保存系统调用号 # %ebx 保存返回状态 # .section .data .section .text .globl _start _start: movl $1, %eax #这是用于退出程序的Linux内核命令号(系统调用) movl

[转载]AngularJS入门教程02:AngularJS模板

是时候给这些网页来点动态特性了——用AngularJS!我们这里为后面要加入的控制器添加了一个测试. 一个应用的代码架构有很多种.对于AngularJS应用,我们鼓励使用模型-视图-控制器(MVC)模式解耦代码和分离关注点.考虑到这一点,我们用AngularJS来为我们的应用添加一些模型.视图和控制器. 请重置工作目录: git checkout -f step-2 我们的应用现在有了一个包含三部手机的列表. 步骤1和步骤2之间最重要的不同在下面列出.,你可以到GitHub去看完整的差别. 视图