【汇编】简单的linux汇编语言程序

一、Linux系统汇编语言

Linux系统上的汇编语言可以使用不同的语法风格,主要包括Intel语法和AT&T语法。这两种语法有各自的特点和风格区别,尽管它们表示的底层机器指令相同。下面分别对两种语法进行简要说明:

Intel语法

Intel语法是由Intel公司为其处理器编写官方文档时所采用的语法。它广泛用于Windows操作系统和一些跨平台的程序中。特点是相对直观,操作数的顺序是"操作 目的地, 源"。这意味着第一个操作数是将要被赋值的对象,而第二个操作数是赋值的值。例如:

mov eax, 1 ; 将数值1赋给寄存器eax

AT&T语法

AT&T语法由Unix系统V的开发者使用,并且在GNU汇编器(GAS)中被广泛采纳。它在用于x86架构上的Linux系统中非常普遍。与Intel语法相反,它采用的是"操作 源, 目的地"的格式。特点是操作数带有明确的大小标识符,如`%eax`(32位寄存器)和`$1`(立即数)。同样的例子在AT&T语法中为:

movl $1, %eax ; 将数值1赋给寄存器eax

两种语法的主要差异

- 操作数顺序:Intel语法以"目标, 源"的顺序,而AT&T语法则相反,采用"源, 目标"。
- 寄存器前缀:AT&T语法使用`%`作为寄存器前缀,而Intel语法不使用。
- 立即数前缀:AT&T语法使用`$`作为立即数前缀,而Intel语法不使用。
- 大小标识符:AT&T语法对操作数的大小使用后缀,如`b`(字节)、`w`(字)、`l`(长字,32位)。
- 地址表示:AT&T语法使用`段寄存器:偏移量(基址寄存器,索引寄存器,比例因子)`的格式,而Intel语法则不同,不使用冒号而是用括号来区分不同的寄存器角色。
- 指令后缀:AT&T语法的指令通常有后缀来标识操作数类型,而Intel语法通常没有指令后缀。
这些差异使得同一个汇编程序在两种语法中看起来非常不同。但无论采用哪种语法,最终产生的机器码是相同的,只是人类编程者的表达方式不同而已。在进行汇编语言编程时,需要根据所使用的工具和个人偏好来选择适合的语法。 

二、Intel语法示例

Linux环境下搭建NASM

1. 安装NASM

在基于Debian的Linux发行版(如Ubuntu)中,可以使用以下命令安装NASM:

   sudo apt updatesudo apt install nasm

在基于Red Hat的发行版(如Fedora或CentOS)中,使用:

sudo dnf install nasm

或者(较旧的版本使用yum):

 sudo yum install nasm
2. 验证安装

   安装完成后,在终端验证NASM版本确认安装成功:

   nasm -v

编写汇编程序

创建一个名为 hello_world.asm 的文本文件,并将以下汇编代码复制到文件中:

section .data               ; 这是数据段
msg db 'Hello, World!', 0xA ; 'Hello, World!' 字符串和一个换行符
len equ $ - msg             ; 字符串长度section .text               ; 以下是代码段
global _start               ; _start 是程序入口_start:; 写入字符串到 stdoutmov eax, 4              ; '4' 是写系统调用的编号mov ebx, 1              ; '1' 是文件描述符 stdoutmov ecx, msg            ; 将消息的地址移到 'ecx'mov edx, len            ; 消息的长度int 0x80                ; 调用内核; 退出程序mov eax, 1              ; '1' 是退出系统调用的编号mov ebx, 0              ; 返回值 0 ,表示无错误int 0x80                ; 调用内核

使用汇编器编译代码

编译刚才写的 hello_world.asm。在终端中运行:

nasm -f elf32 hello_world.asm -o hello_world.o

这将生成一个名为 hello_world.o 的目标文件。

 链接目标文件以创建可执行文件

使用链接器创建可执行程序:

ld -m elf_i386 hello_world.o -o hello_world

此命令会创建一个名为 hello_world 的可执行文件。

运行程序

运行程序并看到其输出:

./hello_world

应该会在屏幕上看到 Hello, World! 的信息。

使用调试器

如果想要观察程序在运行时的具体行为,可以使用调试器,例如 gdb。运行以下命令来启动调试器:

gdb ./hello_world

在 gdb 中,可以设置断点,运行程序,逐步执行指令,并且观察寄存器和内存的状态。例如,要运行程序直到其完成,可以在 gdb 提示符下输入 run 命令:

(gdb) run

要退出 gdb,可以使用 quit 命令。

汇编语言依赖于使用的架构和操作系统。不同的汇编器和链接器可能需要不同的指令和参数。上述示例假设使用基于 Intel 语法的 x86 架构,且在 Linux 系统上。如果在其他平台上工作,需要适当调整这些命令。 

三、AT&T语法示例

GCC允许在C程序中嵌入汇编代码,或者直接编写一个纯汇编文件并使用GCC进行编译和链接。

下面是一个使用AT&T语法的简单汇编程序示例,该程序在Linux系统上打印"Hello, World!"。这个程序是为x86架构编写的,并且假设正在使用32位系统或已经安装了必要的多架构支持。

首先,创建一个名为hello.s的汇编源文件:

# hello.s  
.section .data  
hello_string:  .string "Hello, World!\n"  .section .text  
.global _start  _start:  # 写入系统调用  movl $4, %eax         # 系统调用号 (sys_write)  movl $1, %ebx         # 文件描述符 (stdout)  movl $hello_string, %ecx  # 字符串地址  movl $14, %edx        # 字符串长度(包括换行符)  int $0x80             # 调用内核  # 退出系统调用  movl $1, %eax         # 系统调用号 (sys_exit)  xorl %ebx, %ebx       # 退出状态码  int $0x80             # 调用内核

然后,使用GCC编译并链接这个程序:

gcc -static -o hello hello.s -nostartfiles -nostdlib

这里的编译选项解释如下:

  • -static:生成静态链接的可执行文件,这样就不需要动态链接器来加载运行时库。
  • -nostartfiles:不链接标准启动文件,这些文件通常包含程序入口点(如_start),因为我们已经在汇编代码中提供了。
  • -nostdlib:不链接标准C库,这样GCC就不会自动包含例如libc这样的库。

编译成功后,就可以运行生成的可执行文件了:

./hello

如果一切正常,它应该在终端上打印出"Hello, World!"。

这个程序没有使用C标准库或任何其他的库函数。它直接通过Linux的系统调用来输出字符串和结束程序。此外,这个程序是针对32位系统的;如果正在使用64位系统,需要对代码进行一些修改,包括使用不同的寄存器和系统调用号。在64位系统上,可能还需要使用-m32选项来告诉GCC生成32位代码(并且确保已经安装了必要的32位开发工具和库)。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/257750.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C语言------一种思路解决实际问题

1.比赛名次问题 ABCDE参加比赛&#xff0c;那么每个人的名次都有5种可能&#xff0c;即1&#xff0c;2&#xff0c;3&#xff0c;4&#xff0c;5&#xff1b; int main() {int a 0;int b 0;int c 0;int d 0;int e 0;for (a 1; a < 5; a){for (b 1; b < 5; b){for…

Panalog 日志审计系统 libres_syn_delete.php 前台RCE漏洞复现

0x01 产品简介 Panalog是一款日志审计系统,方便用户统一集中监控、管理在网的海量设备。 0x02 漏洞概述 Panalog日志审计系统 libres_syn_delete.php接口处存在远程命令执行漏洞,攻击者可执行任意命令,接管服务器权限。 0x03 影响范围 version <= MARS r10p1Free 0…

2024.2.10 DMS(数据库管理系统)初体验

数据库管理系统(Database Management System)是一种操纵和管理数据库的大型软件&#xff0c;用于建立、使用和维护数据库&#xff0c;简称DBMS。它对数据库进行统一的管理和控制&#xff0c;以保证数据库的安全性和完整性。用户通过DBMS访问数据库中的数据&#xff0c;数据库管…

OpenCV 笔记(22):图像的缩放——最近邻插值、双线性插值算法

1. 图像缩放 1.1 简介 图像缩放是指通过增加或减少像素来改变图像尺寸的过程&#xff0c;是图像处理中常见的操作。图像缩放会涉及效率和图像质量之间的权衡。 图像放大&#xff08;也称为上采样或插值&#xff09;的主要目的是放大原图像&#xff0c;以便在更高分辨率的显示设…

springboot集成elasticsearch

一、依赖下载 创建好一个springboot项目&#xff0c;需要集成es&#xff1a; 因为springboot默认集成了es&#xff0c;但是版本号需要与本地或者服务器es的版本号一致&#xff0c;我本地es版本是7.14.0&#xff0c;所以需要在<properties></properties>中指定es版…

插值(一)——多项式插值(C++)

插值 插值的作用是可以将原本比较难计算的函数转换为误差在一定范围内的多项式&#xff0c;比如在单片机中直接计算 x 、 log ⁡ 2 x \sqrt{x}、\log_2x x ​、log2​x之类的函数是比较麻烦的&#xff0c;但是使用插值的方法就可以将其转换为误差可控的只有乘法和加减法的多项…

【机器学习案例4】为机器学习算法编码分类数据【含源码】

目录 编码分类数据 序数编码 标签编码 一次性编码 目标编码 目标编码的优点 目标编码的缺点 在现实生活中,收集的原始数据很少采用我们可以直接用于机器学习模型的格式,即数值型数据。因此,需要进行一些预处理,以便以正确的格式呈现数据、选择信息丰富的数据或降低其…

VitePress-12-markdown中使用vue的语法

前言 VitePress 中&#xff0c;markdown文档最终都会转换成为 html文件&#xff0c;我们在访问的时候&#xff0c;也是直接访问的 xxx.html 文件。而且&#xff0c;markdown文档会被作为 [vue单文件] 进行处理&#xff0c;因此&#xff0c;我们我们可以在文档中使用 vue 语法&…

C++ new 和 malloc 的区别?

相关系列文章 C new 和 malloc 的区别&#xff1f; C内存分配策略​​​​​​​ 目录 1.引言 2.区别 2.1.申请的内存分配区域 2.2.类型安全和自动大小计算 2.3.构造函数和析构函数的调用 2.4.异常处理 2.5.配对简便性 2.6.new 的重载 2.7.关键字和操作符 3.总结 1.引…

WebSocket原理详解

目录 1.引言 1.1.使用HTTP不断轮询 1.2.长轮询 2.websocket 2.1.概述 2.2.websocket建立过程 2.3.抓包分析 2.4.websocket的消息格式 3.使用场景 4.总结 1.引言 平时我们打开网页&#xff0c;比如购物网站某宝。都是点一下列表商品&#xff0c;跳转一下网页就到了商品…

OpenGL-ES 学习(4)---- OpenGL-ES 坐标体系

坐标体系 我们知道 OpenGL -ES 坐标系中每个顶点的 x&#xff0c;y&#xff0c;z 坐标都应该在 -1.0 到 1.0 之间&#xff0c;超出这个坐标范围的顶点都将不可见。 将一个物体&#xff08;图像&#xff09;渲染到屏幕上&#xff0c;通常经过将物体坐标转换为标准化设备坐标&am…

高德地图上绘制热力图的方法

百度地图和高德地图的JavaScript API都提供了热力图的绘制方法&#xff0c;都是将热力图作为新的图层&#xff0c;叠加到地图上。但是百度地图的经纬度体系与我们的经纬度存在偏差&#xff0c;高德的与我们相符&#xff0c;应当使用高德地图JavaScript API。 因为是JavaScript…

Elasticsearch:特定领域的生成式 AI - 预训练、微调和 RAG

作者&#xff1a;来自 Elastic Steve Dodson 有多种策略可以将特定领域的知识添加到大型语言模型 (LLM) 中&#xff0c;并且作为积极研究领域的一部分&#xff0c;正在研究更多方法。 对特定领域数据集进行预训练和微调等方法使 LLMs 能够推理并生成特定领域语言。 然而&#…

Mysql的安装、使用、优势与教程

一.安装 1.在小皮的设置界面检测3306端口&#xff0c;保障3306端口可用&#xff1b; 2、在小皮的首面界面&#xff0c;启动MySQL&#xff1b; 3、进行环境变量设置&#xff0c;找到MySQL的路径&#xff0c;进行复制&#xff1b; 4、在Windows的搜索栏内&#xff0c;输入“环境…

Linux 驱动开发基础知识——总线设备驱动模型(七)

个人名片&#xff1a; &#x1f981;作者简介&#xff1a;学生 &#x1f42f;个人主页&#xff1a;妄北y &#x1f427;个人QQ&#xff1a;2061314755 &#x1f43b;个人邮箱&#xff1a;2061314755qq.com &#x1f989;个人WeChat&#xff1a;Vir2021GKBS &#x1f43c;本文由…

Linux——网络通信TCP通信常用的接口和tco服务demo

文章目录 TCP通信所需要的套接字socket()bind()listen()acceptconnect() 封装TCP socket TCP通信所需要的套接字 socket() socket()函数主要作用是返回一个描述符&#xff0c;他的作用就是打开一个网络通讯端口&#xff0c;返回的这个描述符其实就可以理解为一个文件描述符&a…

Vue核心基础5:数据监测、收集表单数据、过滤器

1 数据监测 【代码】 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>总结</title><scrip…

leetcode(二分查找)34.在排序数组中查找元素的第一个和最后一个位置(C++详细解释)DAY11

文章目录 1.题目示例提示 2.解答思路3.实现代码结果 4.总结 1.题目 给你一个按照非递减顺序排列的整数数组 nums&#xff0c;和一个目标值 target。请你找出给定目标值在数组中的开始位置和结束位置。 如果数组中不存在目标值 target&#xff0c;返回 [-1, -1]。 你必须设计…

【最详解】如何进行点云的凹凸缺陷检测(opene3D)(完成度80%)

文章目录 前言实现思路想法1想法2想法3 补充实现想法1想法2代码 想法3代码 总结 前言 读前须知&#xff1a; 首先我们得确保你已经完全知晓相关的基本的数学知识&#xff0c;其中包括用最小二乘法拟合曲二次曲面&#xff0c;以及曲面的曲率详细求解。若还是没弄清楚&#xff0…

(17)Hive ——MR任务的map与reduce个数由什么决定?

一、MapTask的数量由什么决定&#xff1f; MapTask的数量由以下参数决定 文件个数文件大小blocksize 一般而言&#xff0c;对于每一个输入的文件会有一个map split&#xff0c;每一个分片会开启一个map任务&#xff0c;很容易导致小文件问题&#xff08;如果不进行小文件合并&…