汇编语言学习(3)

更好的阅读体验,请点击 YinKai 's Blog 。

内存段

​ 上面讨论的汇编程序的三个部分,也代码各种内存段。

​ 有趣的是,如果将 section 关键字替换为 segment,将会得到相同的结果,这是因为对于汇编器而言,这两个关键字在某些上下文中是可以互相使用的,这两个关键字都是为了告诉汇编器下面的代码是代码段。

内存段

​ 在分段内存模型中,系统内存被划分为不同的独立段组,每个段组由位于段寄存器中的指针引用。

​ 每个段用于包含特定类其型的数据。其中一个段用于包含指令代码,另一个段用于存储数据元素,第三个段用于保存程序堆栈。

​ 这种划分使得程序可以更灵活地管理内存,有选择地引用不同类型的数据和指令,从而更有效地执行各种计算任务。

​ 因此,我们可以将各种内存段指定为:

  • **数据段:由 .data 部分和 .bss 部分表示。 .data 部分用于声明内存区域,其中为程序存储数据元素,该部分在数据元素声明后无法扩展,并且在整个程序中保持静态。.bss 部分也是一个静态内存部分,其中包含稍后在程序中声明的数据的缓冲区。该缓冲区被零填充。
  • **代码段:**它由 .text 部分表示。这定义了内存中存储指令代码的区域。这也是一个固定区域。
  • **堆栈:**该段包含传递给程序内的函数和过程的数据值。

寄存器

​ 处理器操作主要涉及对数据的处理,而数据通常存储在内存中。然而,内存访问可能会降低处理器速度,因为它需要通过控制总线发送请求并进行复杂的内存访问。

​ 为了提高速度,处理器包含一些内部存储位置,称为寄存器。

处理器寄存器

​ IA-32架构中包含 10 个 32 位和 6 个 16 位的处理器寄存器,主要分为三类:

  1. **通用寄存器:**通用寄存器用于存储临时数据,进行算术、逻辑运算等操作。
  2. **控制寄存器:**控制寄存器用于控制和反映处理器的状态。
  3. **段寄存器:**段寄存器用于存储各个段的起始地址,实现内存访问和管理。

​ 通用寄存器进一步可以分为:

  1. 数据寄存器
  2. 指针寄存器
  3. 索引寄存器
数据寄存器

​ 在IA-32架构中,有四个32位的数据寄存器,分别是EAX、EBX、ECX、EDX。这些寄存器可以按照不同的位数划分为更小的寄存器,具体如下:

  • 作为完整的32位数据寄存器:EAX、EBX、ECX、EDX。
  • 32 位寄存器的下半部分可用作四个 16 位数据寄存器:AX、BX、CX 和 DX。
  • 上述4个16位寄存器的下半部分和上半部分可以用作8个8位数据寄存器:AH、AL、BH、BL、CH、CL、DH和DL。

​ 一些数据寄存器在算术运算中具有特定用途:

  • AX: 主累加器,用于输入/输出和大多数算术指令。例如,在乘法运算中,根据操作数的大小将一个操作数存储在EAX或AX或AL寄存器中。
  • BX: 被称为基址寄存器,用于索引寻址。
  • CX: 被称为计数寄存器,与ECX一样,存储迭代操作中的循环计数。
  • DX: 数据寄存器,用于输入/输出操作,与AX寄存器和DX一起使用,用于涉及大值的乘法和除法运算。
指针寄存器

​ 指针寄存器是指 32 位的 EIP、ESP 和 EBP 寄存器以及相应的 16 位 右部分 IP、SP 和 BP。

​ 指针寄存器可以分为三类:

  1. **指令指针(IP):**16 位 IP 寄存器存储下一条要执行的指令的偏移地址。 IP 与 CS 寄存器(代码段)(如CS : IP)关联,给出了代码段中当前指令的完整地址。
  2. 堆栈指针(SP): 16 位 SP 寄存器提供程序堆栈内的偏移值。 SP 与 SS 寄存器(堆栈段)(SS:SP)相关,指的是程序堆栈中数据或地址的当前位置。
  3. 基址指针(BP): 16 位 BP 寄存器主要帮助引用传递给子程序的参数变量。 SS 寄存器中的地址与 BP 中的偏移量相结合,得到参数的位置。 BP 还可以与 DI、SI(索引寄存器) 组合作为基址寄存器进行特殊寻址。
索引寄存器

​ 索引寄存器包括32位的 ESI 和 EDI 以及它们的 16 位最右边的部分。SI 和 DI 通常用于索引寻址,并有时用于执行加法和减法操作。这两个索引指针分别是:

  1. 来源索引 (SI): 用作字符串操作的源索引。在字符串处理中,SI通常用于指向源字符串的当前位置。
  2. 目的地索引 (DI): 用作字符串操作的目标索引。DI通常用于指向目标字符串的当前位置,特别是在字符串复制等操作中。
控制寄存器

​ 控制寄存器包括 32 位指令指针寄存器和 32 位标志寄存器,用于管理程序的执行流程和状态。其中的常见标志位有:

  • 溢出标志 (OF): 表示有符号算术运算后数据的高位(最左位)是否溢出。

  • 方向标志 (DF): 确定移动或比较字符串数据的左或右方向。DF为0时,字符串操作从左到右;DF为1时,字符串操作从右到左。

  • 中断标志 (IF): 决定是否忽略或处理外部中断,如键盘输入。IF为0时禁用外部中断,为1时启用中断。

  • 陷阱标志 (TF): 允许将处理器设置为单步模式,以便一次执行一条指令,常用于调试。

  • 符号标志 (SF): 显示算术运算结果的符号,由最左边位的高位表示。SF为0表示正结果,为1表示负结果。

  • 零标志 (ZF): 表示算术或比较运算的结果是否为零。ZF为1表示零结果,为0表示非零结果。

  • 辅助进位标志 (AF): 包含算术运算后从位 3 到位 4 的进位,用于特殊的算术操作。

  • 奇偶校验标志 (PF): 表示算术运算结果中1位的总数,用于奇偶校验。PF为1表示奇数个1位,为0表示偶数个1位。

  • 进位标志 (CF): 包含算术运算后从高位(最左边)的进位,也存储shift或rotate操作的最后一位内容。

段寄存器

​ 段在计算机内存中是为了组织和管理存储空间而引入的概念。在汇编编程中,处理器通过段寄存器来访问内存位置。以下是关于段的主要信息:

  1. 代码段(CS):
    • 包含要执行的指令的区域。
    • 由 16 位代码段寄存器(CS 寄存器)存储代码段的起始地址。
  2. 数据段(DS):
    • 包含数据、常量和工作区的区域。
    • 由 16 位数据段寄存器(DS 寄存器)存储数据段的起始地址。
  3. 堆栈段(SS):
    • 包含过程或子例程的数据和返回地址,实现为堆栈数据结构。
    • 由16位堆栈段寄存器(SS 寄存器)存储堆栈的起始地址。
  4. 其他段寄存器:
    • 额外段(ES): 提供额外的段来存储数据。
    • FS 和 GS: 提供额外的段用于特定目的。

​ 在汇编编程中,程序需要访问内存位置。段内的所有内存位置都相对于段的起始地址。段从可被 16 整除的地址开始,因此所有这类内存地址中最右边的十六进制数字通常是 0。为了引用段中的任何内存位置,处理器将段寄存器中的段地址与该位置的偏移值组合起来。

示例

​ 下面的程序会在代码中输出 9 个连续的星号。

section	.textglobal _start	 ;必须为链接器声明(gcc)_start:	         ;告诉链接器入口点mov	edx,len  ;消息长度mov	ecx,msg  ;要写入的消息mov	ebx,1    ;文件描述符(stdout)mov	eax,4    ;系统调用号(sys_write)int	0x80     ;调用内核mov	edx,9    ;消息长度mov	ecx,s2   ;要写入的消息mov	ebx,1    ;文件描述符(stdout)mov	eax,4    ;系统调用号(sys_write)int	0x80     ;调用内核mov	eax,1    ;系统调用号(sys_exit)int	0x80     ;调用内核section	.data
msg db 'Displaying 9 stars',0xa ;一条消息
len equ $ - msg  ;消息的长度
s2 times 9 db '*' ;9个星号

​ 我们使用以下命令进行编译和执行:

nasm -f elf nine_stars.asm 
ld -m elf_i386 -s -o nine_stars nine_stars.o

​ 输出结果如下:

Displaying 9 stars
*********

系统调用

​ 系统调用是用户空间和内核空间之间接口的 API。我们之前已经使用过了 sys_write 和 sys_exit 这两个系统调用,分别用于写入屏幕和退出程序。

Linux 系统调用

​ 我们在汇编程序中使用系统调用,需要按照如下步骤:

  1. 将系统调用号放入 EAX 寄存器中;
  2. 将系统调用的参数存储在 EBX、ECX 等寄存器中
  3. 调用相关中断(0x80),然后执行 EAX 中的系统调用号对应的程序
  4. 结果通常返回 EAX 寄存器中

​ 可以存储系统调用参数的存储器有 基址寄存器 EBX、计数寄存器 ECX、数据寄存器 EDX、源索引寄存器 ESI、目标索引寄存器 EDI、基址指针寄存器 EBP。

​ 下面给大家演示一下几个示例:

​ (1)使用 sys_exit:

mov eax, 1 ; 系统调用号 sys_exit
int 0x80   ; 调用内核

​ (2)使用 sys_write:

mov edx, 4		; 消息长度
mov ecx, msg	; 要写入的消息
mov ebx, 1		; 文件描述符
mov eax, 4		; 系统调用号
int 0x80		; 调用内核
常见系统调用
%eaxName%ebx%ecx%edx%esx%edi
1sys_exitint----
2sys_forkstruct pt_regs----
3sys_readunsigned intchar *size_t--
4sys_writeunsigned intconst char *size_t--
5sys_openconst char *intint--
6sys_closeunsigned int----
示例

​ 下面举一个复杂一点的例子,包含了之前我们讲过的 data、bss、text 三个部分,也希望通过这个例子,加深一下大家对 data 部分和 bss 部分的区别

section .data                           ; 数据段userMsg db '请输入一个数字: '        ; 提示用户输入数字的消息lenUserMsg equ $-userMsg             ; 消息的长度dispMsg db '您输入的是: 'lenDispMsg equ $-dispMsg                 section .bss           ; 未初始化的数据num resb 5            ; 用于存储用户输入的变量,5字节section .text          ; 代码段global _start        ; 声明程序入口点_start:                ; 程序入口; 输出提示消息 '请输入一个数字: 'mov eax, 4mov ebx, 1mov ecx, userMsgmov edx, lenUserMsgint 80h; 读取并存储用户输入mov eax, 3mov ebx, 2mov ecx, num  mov edx, 5          ; 读取5字节的信息(数字和符号,1字节)int 80h	; 输出消息 '您输入的是: 'mov eax, 4mov ebx, 1mov ecx, dispMsgmov edx, lenDispMsgint 80h  ; 输出用户输入的数字mov eax, 4mov ebx, 1mov ecx, nummov edx, 5int 80h  ; 退出程序mov eax, 1mov ebx, 0int 80h

​ 同样,我们需要通过下述命令来编译运行:

nasm -f elf get_num.asm 				# 将汇编程序编译成机器码
ld -m elf_i386 -s -o get_num get_num.o	# 将目标文件和其他必要的文件组合成可执行文件
./get_num 								# 运行可执行文件

​ 输出结果如下:

请输入一个数字: 
123
您输入的是: 123

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

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

相关文章

web应用开发技术的一些概念

一、Servlet 1.Servlet的工作过程: Servelt的工作流程示意图 (1)客户端发起一个Http请求到服务器,请求特定的资源或者是要执行特定的操作 (2)服务器在接收到请求后,根据请求相应的URL将请求分发…

PostgreSQL进阶操作

PostgreSQL进阶操作 SQL执行顺序 (9) SELECT (10) DISTINCT col1, [OVER()] (6) AGG_FUNC(col2) (1) FROM table1 (3) JOIN table2 (2) ON table1.col table2.col (4) WHERE constraint_expression (5) GROUP BY col (7) WITH CUBE|ROLLUP (8) HAVING constraint_expression…

21、同济、微软亚研院、西安电子科技大提出HPT:层次化提示调优,独属于提示学习的[安妮海瑟薇]

前言: 本论文由同济大学、微软亚洲研究院、西安电子科技大学,于2023年12月11日中了AAAI2024 论文: 《Learning Hierarchical Prompt with Structured Linguistic Knowledge for Vision-Language Models》 地址: [2312.06323]…

C++泛型超详细合集-泛化的编程方式-程序员编写一个函数/类的代码让编译器去填补出不同的函数实现-供大家学习研究参考

以Add函数为例&#xff0c;在函数模板存在的同时&#xff0c;我们还可以单独写一个int类型的add函数。这都归功于函数重载的存在。 同时&#xff0c;我们还可以使用<int>来指定函数模板重载为已存在的Add函数。因为本质上这两个函数是不同的&#xff0c;并不会冲突。 下…

js 数据类型

js的八种数据类型&#xff1a; 基本类型&#xff08;基本类型&#xff09;&#xff1a;Number&#xff0c;String&#xff0c;Boolean&#xff0c;Undefined&#xff0c;Null&#xff0c;Symbol 引用数据类型&#xff08;对象类型&#xff09;&#xff1a;Object&#xff0c;…

mybatis中xml文件容易搞混的属性

目录 第一章、1.1&#xff09;MyBatis中resultMap标签1.2&#xff09;MyBatis的resultType1.3&#xff09;MyBatis的parameterType1.4&#xff09;type属性1.5&#xff09;jdbcType属性1.6&#xff09;javaType属性1.7&#xff09;ofType属性 友情提醒: 先看文章目录&#xff…

【k8s】--insecure-registry详解 ( 访问仓库、https、http)

文章目录 一、--insecure-registry是什么二、如何使用--insecure-registry三、--insecure-registry的安全风险四、--insecure-registry的替代方案五、总结参考 一、–insecure-registry是什么 --insecure-registry是docker中用来设置与docker registry通信的安全限制的一个参数…

猫粮哪个牌子好又安全?好又安全的主食冻干猫粮牌子推荐

现在越来越多的铲屎官关注猫咪的食品选择&#xff0c;而冻干猫粮一直是热门话题。其中主食冻干的肉含量很高&#xff0c;富含猫咪成长所需的蛋白质、维生素等营养物质。而且冻干工艺还保留了食材的原始风味&#xff0c;复水后可以恢复鲜肉的口感&#xff0c;猫咪很喜欢吃&#…

人工智能Keras图像分类器(CNN卷积神经网络的图片识别篇)

上期文章我们分享了人工智能Keras图像分类器(CNN卷积神经网络的图片识别的训练模型),本期我们使用预训练模型对图片进行识别:Keras CNN卷积神经网络模型训练 导入第三方库 from keras.preprocessing.image import img_to_array from keras.models import load_model impor…

.net web API的文件传输(上传和下载)客户端winform

防止反复造轮子&#xff0c;直接上代码。 客户端代码如下&#xff1a; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.IO; using System.IO.Compression; using System.Linq; using …

conda channel的镜像设置

目录 前言1 显示所有channel2 移除清华镜像3 添加可用的清华源4 下载opencv5 一些其他的conda指令参考文献 ———————————————— 版权声明&#xff1a;本文为CSDN博主「宇内虹游」的原创文章&#xff0c;遵循CC 4.0 BY-SA版权协议&#xff0c;转载请附上原文出处链…

关于“Python”的核心知识点整理大全27

目录 10.5 小结 第&#xff11;1 章 测试代码 11.1 测试函数 name_function.py 函数get_formatted_name()将名和姓合并成姓名&#xff0c;在名和姓之间加上一个空格&#xff0c;并将它们的 首字母都大写&#xff0c;再返回结果。为核实get_formatted_name()像期望的那样工…

arcgis javascript api4.x加载天地图cgs2000坐标系

需求&#xff1a;arcgis javascript api4.x加载天地图cgs2000坐标系 效果&#xff1a; 示例代码&#xff1a; <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"wid…

《LeetCode力扣练习》代码随想录——双指针法(反转字符串---Java)

《LeetCode力扣练习》代码随想录——双指针法&#xff08;反转字符串—Java&#xff09; 刷题思路来源于 代码随想录 344. 反转字符串 相向双指针 class Solution {public void reverseString(char[] s) {if(s.length1){return;}int left0;int rights.length-1;while(left<r…

Python爬虫-解决使用requests,Pyppeteer,Selenium遇到网站显示“您的连接不是私密连接”的问题|疑难杂症解决(2)

前言 本文是该专栏的第13篇,后面会持续分享python爬虫案例干货,记得关注。 相信很多同学在处理爬虫项目的时候,会遇到一些网站出现如下图所示的情况: 就是当你不论是使用requests进行协议请求,还是使用自动化框架pyppeteer或者selenium都会出现上图中的情况。这相信会或多…

查找书籍(缓冲区)

给定n本书的名称和定价&#xff0c;本题要求编写程序&#xff0c;查找并输出其中定价最高和最低的书的名称和定价。 输入格式: 输入第一行给出正整数n&#xff08;<10&#xff09;&#xff0c;随后给出n本书的信息。每本书在一行中给出书名&#xff0c;即长度不超过30的字…

年度大盘点:AIGC、AGI、GhatGPT震撼登场!揭秘人工智能大模型的奥秘与必读书单

这里写目录标题 前言01 《ChatGPT 驱动软件开发》02 《ChatGPT原理与实战》03 《神经网络与深度学习》04 《AIGC重塑教育》05 《通用人工智能》 前言 在2023年&#xff0c;人工智能领域经历了一场前所未有的大爆发&#xff0c;特别是在语言模型领域。新的概念和英文缩写如AIGC、…

Ngnix之反向代理、负载均衡、动静分离

目录 1. Ngnix 1.1 Linux系统Ngnix下载安装 1.2 反向代理 正向代理&#xff08;Forward Proxy&#xff09;&#xff1a; 反向代理&#xff08;Reverse Proxy&#xff09;&#xff1a; 1.3 负载均衡 1.4 动静分离 1. Ngnix Nginx是一个高性能的开源Web服务器&#xff0…

设备运维管理系统,设备列表管理,设备拓扑图关系图,告警日志运维

个人主页&#xff1a; 左本Web3D&#xff0c;更多案例预览请点击》 在线案例 个人简介&#xff1a;专注Web3D使用ThreeJS实现3D效果技巧和学习案例 &#x1f495; &#x1f495;积跬步以至千里&#xff0c;致敬每个爱学习的你。喜欢的话请三连&#xff0c;有问题请私信或者加微…

C# 图解教程 第5版 —— 第19章 枚举器和迭代器

文章目录 19.1 枚举器和可枚举类型19.2 IEnumerator 接口19.3 IEnumerable 接口19.4 泛型枚举接口19.5 迭代器19.5.1 迭代器块19.5.2 使用迭代器来创建枚举器19.5.3 使用迭代器来创建可枚举类型 19.6 常见迭代器模式19.7 产生多个可枚举类型19.8 将迭代器作为属性19.9 迭代器的…