C/C++汇编学习(三)——指令集-汇编基础

        汇编语言是一种用于与计算机硬件直接交互的低级编程语言。它非常接近机器语言,但提供了更易于理解的符号来表示机器指令和数据。不同的处理器架构有不同的汇编语言。例如,x86架构用于大多数个人电脑,而ARM架构常见于移动设备。

目录

1. 指令集

x86 指令集

1. 数据处理指令

2. 数据传输指令

3. 控制流指令

4. 字符串和重复操作指令

5. 位操作指令

6. 特殊和系统指令

7. SIMD指令

ARM 指令集

1. 数据处理指令

2. 数据传输指令

3. 分支指令

4. 条件执行指令

5. 浮点和SIMD指令

6. 特殊指令

7. 控制寄存器指令

指令分类

1. 数据处理指令

2. 数据传输指令

3. 控制流指令

4. 特殊指令

5. SIMD和浮点指令

6. 状态和控制寄存器操作

7. 字符串和重复操作指令

2. 寄存器

1. 通用寄存器

2. 指令指针寄存器

3. 栈指针寄存器

4. 标志寄存器

5. 特殊寄存器

3. 基本的汇编指令

1. MOV 指令

2. ADD 指令

3. SUB 指令

4. 分支和循环

5. 栈操作

6. 函数调用和返回

7. 内联汇编

总结


1. 指令集

        指令集是一组基本操作,由特定的处理器架构定义。这些操作包括数据处理、数据传输、逻辑操作和控制流指令。每种架构都有其独特的指令集,例如x86和ARM的指令集就大不相同。

x86 指令集

x86 指令集主要用于个人电脑和服务器,是最广泛使用的指令集之一。其特点包括:

  • 富含指令的集合:x86 指令集包含大量的指令,涵盖了从基本的数学运算到复杂的系统调用和硬件控制等多种操作。
  • 复杂指令集计算机(CISC):x86 属于CISC架构,意味着它包含一些执行多个低级操作的复杂指令。
  • 可变长度指令:x86指令的长度不固定,这使得指令集在设计上更为灵活,但也增加了解码指令的复杂性。
  • 支持多种寻址模式:x86 指令集提供多种数据寻址方式,如直接寻址、间接寻址、基址加偏移寻址等。

1. 数据处理指令

这些指令用于执行基本的数学和逻辑运算。

  • ADD, SUB, MUL, DIV:分别用于加法、减法、乘法和除法运算。
  • INC, DEC:分别用于将操作数递增和递减。
  • AND, OR, XOR, NOT:逻辑运算指令,分别执行与、或、异或和非操作。

2. 数据传输指令

用于在寄存器、内存和I/O端口之间移动数据。

  • MOV:将数据从一个位置移动到另一个位置。
  • PUSH, POP:用于操作堆栈,分别是入栈和出栈操作。
  • IN, OUT:用于与I/O端口通信。

3. 控制流指令

这些指令控制程序的执行流程。

  • JMP:无条件跳转到指定地址。
  • JE, JNE, JG, JL 等:条件跳转指令,根据比较结果跳转。
  • CALL, RET:分别用于函数调用和从函数返回。

4. 字符串和重复操作指令

用于处理字符串和重复操作。

  • MOVS, CMPS, SCAS:用于字符串移动、比较和扫描。
  • REP, REPE, REPNE:重复执行字符串操作指令。

5. 位操作指令

用于位级操作。

  • SHL, SHR:分别是逻辑左移和逻辑右移。
  • ROL, ROR:分别是循环左移和循环右移。

6. 特殊和系统指令

  • INT:产生软件中断。
  • NOP:无操作。
  • HLT:停止处理器的执行,直到下一个外部中断。

7. SIMD指令

  • 例如 SSE, SSE2, AVX 系列指令,用于同时处理多个数据。

ARM 指令集

ARM 指令集广泛用于移动设备、嵌入式系统和最近的一些个人电脑。其特点包括:

  • 简单指令集计算机(RISC):ARM 属于RISC架构,指令集较为简单,每条指令通常只执行一个操作。
  • 固定长度指令:大多数ARM指令长度固定,这简化了指令流的解析和执行。
  • 高能效:ARM架构注重能效比,适用于电池供电的设备。
  • 条件执行指令:ARM指令集支持条件执行,这可以减少分支指令的使用,提高程序的效率。

1. 数据处理指令

这些指令用于执行基本的数学和逻辑运算。

  • ADD, SUB:加法和减法。
  • MUL, DIV:乘法和除法。
  • AND, ORR, EOR, BIC:逻辑与、或、异或和位清除。

2. 数据传输指令

用于在寄存器、内存之间移动数据。

  • LDR, STR:加载和存储指令。
  • LDM, STM:加载和存储多个寄存器的内容。

3. 分支指令

控制程序的流程。

  • B, BL:无条件分支和带链接的分支(用于函数调用)。
  • BX, BLX:跳转到寄存器中地址的指令。

4. 条件执行指令

ARM的特色之一,可以在特定条件下执行指令。

  • 指令后缀如 EQ, NE, GT, LT 等,表示等于、不等于、大于、小于等条件。

5. 浮点和SIMD指令

用于浮点计算和单指令多数据操作。

  • VADD, VSUB, VMUL, VDIV:浮点加法、减法、乘法和除法。
  • VMLA, VMLS:浮点乘加和乘减。

6. 特殊指令

  • SVC(原 SWI):用于发起软件中断。
  • NOP:无操作。
  • WFI, WFE:等待中断和等待事件。

7. 控制寄存器指令

用于控制程序状态寄存器。

  • MRS, MSR:用于读取和设置程序状态寄存器。

指令分类

无论是x86还是ARM,其指令集都可以分为以下几类:

  • 数据处理指令:用于算术运算(如加、减)、逻辑运算(如与、或、非)等。
  • 数据传输指令:用于在寄存器、内存和I/O设备之间传输数据。
  • 控制流指令:改变程序执行顺序的指令,如跳转(JMP)、条件分支(如IF-THEN)等。
  • 特殊指令:用于系统调用、中断处理等特殊操作。

1. 数据处理指令

这些指令用于执行各种算术和逻辑运算。

  • 算术指令:如 ADD(加法),SUB(减法),MUL(乘法),DIV(除法)。
  • 逻辑指令:如 AND(与),OR(或),XOR(异或),NOT(非)。
  • 移位指令:如 SHL(左移),SHR(右移),ROR(循环右移),ROL(循环左移)。

2. 数据传输指令

用于在不同位置之间传输数据。

  • 寄存器间传输:如 MOVPUSHPOP
  • 内存访问:如 LDRSTR(ARM),LOADSTORE(x86)。
  • I/O操作:如 INOUT(x86特有)。

3. 控制流指令

控制程序执行的流程。

  • 跳转指令:如 JMPCALLRET
  • 条件分支:如 JE(如果等于则跳转),JNE(如果不等于则跳转)等。
  • 循环控制:如 LOOPJLE(如果小于或等于则跳转)。

4. 特殊指令

用于特定的操作和处理器控制。

  • 系统调用和中断:如 INTSYSCALL
  • 特权指令:如用于控制处理器状态的 STI(设置中断标志),CLI(清除中断标志)。
  • 无操作指令:如 NOP

5. SIMD和浮点指令

处理向量和浮点数。

  • 单指令多数据(SIMD)操作:如 SSEAVX 指令集(x86);NEON(ARM)。
  • 浮点运算:如 FADDFSUBFMUL

6. 状态和控制寄存器操作

用于管理处理器状态。

  • 标志和控制寄存器操作:如 MSRMRS(ARM),LIDT(x86)。

7. 字符串和重复操作指令

针对字符串和重复数据的高效处理。

  • 字符串操作:如 MOVSCMPS
  • 循环和重复操作:如 REPREPE

2. 寄存器

寄存器是处理器内部的小容量存储位置,用于快速访问重要的数据和指令。每个架构都有一组特定的寄存器,常见的寄存器包括:

  • 通用寄存器:用于存储临时数据和地址。
  • 指令指针寄存器:存储下一条执行指令的地址。
  • 栈指针寄存器:指向当前栈顶的位置。
  • 标志寄存器:包含执行结果的状态信息,如零位、进位位等。

1. 通用寄存器

通用寄存器可用于多种目的,如存储中间计算结果、地址等。在不同的架构中,通用寄存器的数量和用途可能有所不同。

  • x86架构:包括AX, BX, CX, DX等。这些寄存器可以进一步分为高低两部分(如AH和AL是AX的高位和低位)。随着架构的发展,引入了更多的扩展寄存器,如EAX, EBX, ECX, EDX(32位),RAX, RBX, RCX, RDX(64位)。
  • ARM架构:通常有R0到R15等寄存器,其中R13通常用作栈指针(SP),R14作为链接寄存器(LR),R15作为程序计数器(PC)。

2. 指令指针寄存器

指令指针寄存器(Program Counter, PC)存储下一条要执行的指令的地址。

  • x86架构:称为程序计数器(PC)或指令指针(IP)。
  • ARM架构:R15寄存器充当程序计数器。

3. 栈指针寄存器

栈指针寄存器(Stack Pointer, SP)指向当前栈顶的位置。它在函数调用和返回过程中起着重要作用,用于管理函数的调用栈。

  • x86架构:ESP(32位)和RSP(64位)寄存器用作栈指针。
  • ARM架构:R13寄存器通常用作栈指针。

4. 标志寄存器

标志寄存器(Flag Register)用于存储处理器状态、指示指令执行的结果。

  • x86架构:EFLAGS(32位)和RFLAGS(64位)寄存器包含多个标志位,如零标志(ZF)、进位标志(CF)、溢出标志(OF)等。
  • ARM架构:程序状态寄存器(Program Status Registers, PSRs)包括应用程序状态寄存器(APSR)中的标志位,如N(负),Z(零),C(进位),V(溢出)。

5. 特殊寄存器

除了上述常见类型,还有一些特殊用途的寄存器。

  • 段寄存器(x86特有):如CS(代码段寄存器)、DS(数据段寄存器)等,用于支持x86的内存分段机制。
  • 链接寄存器(ARM特有):R14寄存器,用于存储函数调用的返回地址。

3. 基本的汇编指令

汇编语言中常见的基本指令包括:

  • MOV:数据传输指令,用于将数据从一个位置移动到另一个位置。
  • ADD:算术加法指令,用于将两个数值相加。
  • SUB:算术减法指令,用于从一个数值中减去另一个数值。

        汇编语言确实提供了对硬件的直接控制能力,特别是在需要精确控制硬件行为或优化性能的场景中。下面是x86架构中MOV, ADD, 和 SUB 指令的详细介绍和示例。

1. MOV 指令

  MOV 指令用于将数据从一个位置移动到另一个位置。它不进行任何算术或逻辑操作,仅仅是数据传输。

MOV AX, 5     ; 将立即数 5 移动到 AX 寄存器
MOV BX, AX    ; 将 AX 寄存器中的值复制到 BX 寄存器

2. ADD 指令

  ADD 指令用于将两个数值相加。它是最基本的算术运算指令之一。

MOV AX, 5     ; 将 5 移动到 AX 寄存器
ADD AX, 3     ; 将 AX 寄存器中的值与 3 相加,结果存回 AX

3. SUB 指令

   SUB 指令用于从一个数值中减去另一个数值。

MOV AX, 10    ; 将 10 移动到 AX 寄存器
SUB AX, 4     ; 将 AX 寄存器中的值与 4 相减,结果存回 AX

4. 分支和循环

        在汇编语言中,控制流的操作通常涉及条件分支和循环。这个例子中,CMP 指令用于比较两个寄存器的值,JEJNE 是条件跳转指令,它们根据比较的结果跳转到不同的代码段。

CMP AX, BX       ; 比较 AX 和 BX 的值
JE equal         ; 如果 AX 等于 BX,则跳转到标签 'equal'
JNE notequal     ; 如果 AX 不等于 BX,则跳转到标签 'notequal'
equal:; 在这里编写 AX 等于 BX 时的代码JMP end
notequal:; 在这里编写 AX 不等于 BX 时的代码
end:

        这里,LOOP 指令用于实现循环。它每次迭代都会减少 CX 寄存器的值,并且当 CX 不为 0 时跳回到循环的开始

MOV CX, 5    ; 初始化计数器
loop_start:; 循环体的代码LOOP loop_start ; 减少 CX 的值,如果 CX 不为 0,则跳回到 loop_start

5. 栈操作

        栈是一种重要的数据结构,用于实现函数调用、参数传递等。

PUSH AX       ; 将 AX 寄存器的值压入栈中
PUSH BX       ; 将 BX 寄存器的值压入栈中
POP CX        ; 将栈顶的值弹出到 CX 寄存器

6. 函数调用和返回

        在汇编中,函数调用涉及将参数放入寄存器或栈中,然后使用 CALL 指令调用函数。

CALL myFunction ; 调用函数
myFunction:; 函数体RET           ; 返回

  CALL 指令用于调用函数,RET 指令用于从函数返回。

7. 内联汇编

        在高级语言(如C或C++)中,内联汇编允许将汇编指令直接嵌入到源代码中。这种方法结合了高级语言的易用性和汇编语言的强大能力。

int a = 10, b = 20, sum;
asm ("MOV %1, %%eax\n\t""ADD %2, %%eax\n\t""MOV %%eax, %0": "=r" (sum)      /* 输出 */: "r" (a), "r" (b) /* 输入 */: "%eax"           /* 被改变的寄存器 */);

        在这个例子中,asm 关键字用于嵌入汇编代码。该代码将 ab 的值相加,并将结果存储在 sum 中。 

总结

        汇编语言允许程序员直接操控硬件,理解和操作处理器的内部机制。这在系统编程、嵌入式系统、操作系统开发等领域非常重要。不过,由于汇编语言高度依赖于具体的硬件架构,因此通常不如高级语言(如C++或Python)那样具有可移植性。

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

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

相关文章

微信小程序:flex常用布局

在我们平时微信小程序开发过程中为了页面能达到设计小伙伴的预期,追求还原度,那我们肯定会使用很多常用的布局方式,那我们今天就介绍一下微信小程序中常用的一些flex布局 1、常用flex布局 /** 水平垂直居中 **/ .flex-center {display: fle…

vue3+vant4 移动端软键盘弹出 收起导致项目样式布局错乱解决方案,亲测有效!!

问题描述 最近在做vue3 H5的移动端项目 我用的是vue3vant4,然后在使用过程中发现 小米14手机在点击密码输入框软键盘弹出 时会导致项目布局整体向上移动 导致页面布局错乱。 原因分析: 在移动端软键盘弹出收起时,导致项目样式布局错乱的原因…

基于STM32的ESP8266 WiFi模块数据采集与显示

基于STM32的ESP8266 WiFi模块数据采集与显示是一种常见的嵌入式系统应用,通常用于远程数据监测和控制。在这种应用中,STM32作为主控制器负责采集周围环境的数据,通过ESP8266 WiFi模块将数据发送到远程服务器,并在远程服务器上进行…

03-微服务-Ribbon负载均衡

Ribbon负载均衡 1.1.负载均衡原理 SpringCloud底层其实是利用了一个名为Ribbon的组件,来实现负载均衡功能的。 那么我们发出的请求明明是http://userservice/user/1,怎么变成了http://localhost:8081的呢? 1.2.源码跟踪 为什么我们只输入…

小梅哥Xilinx FPGA学习笔记20——无源蜂鸣器驱动设计与验证(音乐发生器设计)

目录 一:章节导读 二:无源蜂鸣器驱动原理 三:PWM 发生器模块设计 3.1 PWM 发生器模块框图 3.2 PWM 发生器模块接口功能描述 3.3 PWM波生成设计文件代码 3.4 测试仿真文件 3.5 测试仿真结果 3.6 板级调试与验证之顶层文件设计 四&am…

Python:界面开发,wx入门篇

以下内容为本人的学习笔记,如需要转载,请声明原文链接 微信公众号「ENG八戒」https://mp.weixin.qq.com/s/3Yb_YAKiMte_f5HanetXiA 本文大概 3617 个字,阅读需花 10 分钟 内容不多,但也花了一些精力 如要交流,欢迎评…

@Scheduled定时任务现状与改进

项目场景: 定时任务现状:每个项目都会有一些配置信息,这些信息我们是都放在一个配置服务中,这个服务会定时从配置表中加载所有配置存入本地JVM内存,以供调用方获取(调用方集成了配置服务的SDK,…

elasticsearch的查询方式和数据库事务隔离级别的思考

项目中用到了 elasticsearch,发现有几种查询方式不太一样,思考了一下,总结如下 普通分页 等同于关系数据库的分页查询,例如 mysql 的 limit,如下 sql select * from test limit 100000,10 这种查询方式有一个问题&a…

K8S学习指南(62)-K8S源代码走读之Kube-Scheduler

文章目录 前言Kube-Scheduler 的代码结构Kube-Scheduler 的核心逻辑1. 调度框架1.1 阶段划分1.2 阶段执行 2. 调度算法2.1 优先级函数2.2 优选函数 3. 调度器插件3.1 预选插件3.2 优选插件3.3 绑定插件 4. 节点选择4.1 候选节点选择4.2 节点权重计算 5. 调度事件处理5.1 调度事…

系列十一、(一)Sentinel简介

一、Sentinel简介 1.1、官网 【英文文档】 https://github.com/alibaba/Sentinel/wiki【中文文档】 https://github.com/alibaba/Sentinel/wiki/%E4%B8%BB%E9%A1%B5 1.2、概述 1.3、功能

网络路由跟踪工具

随着企业网络需求的增长,组织发现监控和管理其网络基础设施变得越来越困难。网络管理员正在转向其他工具和资源,这些工具和资源可以使他们的工作更轻松一些,尤其是在故障排除方面。 目前,网络管理员主要使用简单、免费提供的实用…

Jvm垃圾收集器系列之G1的小知识(个人见解仅供参考)

问:G1收集器有哪些主要特点? 答:G1收集器的主要特点包括:面向服务器、高吞吐量、满足GC停顿时间要求、将Java堆划分为多个大小相等的独立区域(Region)、保留了年轻代和老年代的概念但不再是物理隔阂、对大对…

在win10上cuda12+tensorrt8.6+vs2019环境下编译paddle2.6生成python包与c++推理库

paddle infer官方目前没有发布基于cuda12的c库,为此参考https://www.paddlepaddle.org.cn/inference/user_guides/source_compile.html实现cuda12的编译安装,不料博主才边缘好自己的paddle2.6,paddle官方已经发布了cuda12.0的paddle2.6框架。…

C++ 学习系列 -- using关键字

一 概述 c 11 中新引入了关键字 using 二 using 关键字的用处 1. using namespace 与 using namespace member #include<vector> #include<list>int main() {using namespace std;vector<int> vec {1, 2, 3};using std::list;list<int> li {1,…

C++使用openssl的EVP对文件进行AES-256-CBC加解密

1、背景 有项目需求&#xff0c;有对文件进行加密的功能&#xff0c;经过评估&#xff0c;最终决定使用AES-256-CBC加密。在C中要实现这种加密有很多中方式和第三方库&#xff0c;由于运行环境的限制&#xff0c;可选择的库不多&#xff0c;最终决定使用openssl来进行。 关于AE…

基于多反应堆的高并发服务器【C/C++/Reactor】(中)Buffer的创建和销毁、扩容、写入数据

TcpConnection:封装的就是建立连接之后得到的用于通信的文件描述符&#xff0c;然后基于这个文件描述符&#xff0c;在发送数据的时候&#xff0c;需要把数据先写入到一块内存里边&#xff0c;然后再把这块内存里边的数据发送给客户端&#xff0c;除了发送数据&#xff0c;剩下…

Jvm垃圾收集器系列之CMS收集器(个人见解仅供参考)

问&#xff1a;什么是CMS收集器&#xff1f; 答&#xff1a;CMS&#xff08;Concurrent Mark Sweep&#xff09;收集器是Java HotSpot虚拟机中的一种垃圾收集器&#xff0c;主要用于实现低延迟的垃圾回收。 问&#xff1a;CMS收集器的主要目标是什么&#xff1f; 答&#xff1a…

基于综合特征的细菌噬菌体宿主预测工具iPHoP (Integrated Phage HOst Prediction)的介绍以及使用方法详细流程

介绍 iPHoP&#xff08;Integrated Phage HOst Prediction&#xff09;是一种基于综合特征的细菌噬菌体宿主预测方法。它是通过整合基因组序列、蛋白质序列和宿主基因组信息来预测细菌噬菌体的宿主范围。 iPHoP的预测过程分为三个步骤&#xff1a;特征提取、特征选择和宿主预…

Ubuntu22.04无法启动EasyConnect的问题

转自&#xff1a;https://juejin.cn/post/7121236352032571422 无法启动主要是因为依赖包版本高&#xff0c;不兼容&#xff0c;要降级 解决方法&#xff1a; 1、安装easyconnect&#xff08;已安装就跳过&#xff09; 2、EasyConnect的安装位置在 /usr/share/sangfor/EasyCon…

【Spring实战】21 Spring Data REST 常用功能详细介绍

文章目录 1. 资源导出&#xff08;Resource Exporting&#xff09;2. 查询方法&#xff08;Query Methods&#xff09;3. 分页和排序&#xff08;Pagination and Sorting&#xff09;4. 关联关系&#xff08;Associations&#xff09;5. 事件&#xff08;Events&#xff09;6. …