【计算机组成原理】四、指令系统:3.汇编语言

news2024/11/15 18:32:38

5.汇编语言

文章目录

    • 5.==汇编语言==
      • 5.1考试要求(408)
      • x86汇编语言
      • 5.2地址码
        • x86架构CPU,有哪些寄存器?
        • 总结
      • 5.3操作码
        • 5.3.1算术运算
        • 5.3.2逻辑运算
        • 5.3.3其他
      • 5.4循环分支
        • 5.4.1 jmp直接跳转指令
        • 5.4.2 jxxx条件跳转指令
        • 分支C→汇编
        • 循环C→汇编
        • 用loop指令实现循环
      • 5.5函数调用
        • 5.5.1函数调用栈在内存中的位置
        • 5.5.2两种方式访问栈帧数据
        • 5.5.3函数调用时,如何切换栈帧
        • 5.5.4一个栈帧内可能包含哪些内容?
        • 5.5.5如何传递参数和返回值
        • 总结
      • 5.6汇编格式

高级语言与机器级代码之间的对应:

汇编语言和机器语言都是机器级代码,是一一对应的。

在这里插入图片描述

5.1考试要求(408)

  • 只需关注x86汇编语言;若考察其他汇编语言题目会详细注释。
  • 题目给出某段简单程序的c语言、汇编语言、机器语言表示。能结合c语言看懂汇编语言的关键语句(看懂常见指令、选择结构、循环结构、函数调用)。
  • 汇编语言、机器语言一一对应,要能结合汇编语言分析机器语言指令的格式、寻址方式。

不会考:将c语言人工翻译为汇编语言或机器语言。

x86汇编语言

mov为例子:

mov 要移动到的位置destination, 被移动的内容/位置source;

mov eax, ebx				#寄存器→寄存器
mov eax, dword ptr [af996h]	#主存→寄存器
mov eax, 5 					#立即数→寄存器

#将ebx所指主存地址的32bit复制到eax寄存器中(寄存器间接寻址)
mov eax, dword ptr [ebx]	
mov eax,[ebx]				#若未指明主存读写长度,默认32 bit

#将eax的内容复制到af996h所指的地址
mov [af996h], eax			#未指明长度默认32bit

#将eax的内容复制到ebx所指主存地址的32bit
mov dword ptr [ebx], eax

#将ebx所指的主存地址的8bit复制到eax
mov eax, byte ptr [ebx]

#将ebx+8所指主存地址的32bit 复制到eax寄存器中
mov eax, dword ptr [ebx+8]
#将af996-12所指主存地址的 32bit复制到eax寄存器中
mov eax, dword ptr [af996-12h]

在这里插入图片描述

5.2地址码

x86架构CPU,有哪些寄存器?

每个寄存器都是32bit,32bit = Extended = E

都是E开头的,包含32bit数据。

  1. 通用寄存器 X

    • EAX
    • EBX
    • ECX
    • EDX
  2. 变址寄存器 I = index

    变址寄存器可用于线性表字符串的处理。

    • ESI: source index(被移动的)
    • EDI: destination index(要移动到的目的)
  3. 堆栈寄存器 P = pointer

    用于函数调用

    • EBP: 堆栈指针base pointer
    • ESP: 堆栈指针stack pointer

在这里插入图片描述

  • 通用寄存器还可以使用一半寄存器(低16位)

AX, BX, CX, DX:16bit

在这里插入图片描述

两个变址寄存器只能固定使用32bit;
两个堆栈寄存器只能固定使用32bit。

  • 甚至还可以使用1/4=8bit:

AL, AH
BL, BH

在这里插入图片描述

总结

在这里插入图片描述

5.3操作码

操作码 地址码
操作码 d, s

#王道书中:
add <reg>/<mem>, <reg>/<mem>/<con>
#要注意,一般不建议同时访问两个主存:
add <mem>, <mem>	# ×,访存太多是不可以的
  • destination:目的地(d 目的操作数)
  • source:来源地(s 源操作数)

目的操作数d不可以是常量,因为进行完操作之后还要把数据放到d的位置。

还有:

  • reg:寄存器register
  • mem:内存memory
  • con:常数constant
5.3.1算术运算
功能英文汇编指令注释
addadd d, s#计算d+s,结果存入d
subtractsub d, s#计算d-s,结果存入d
multiplymul d, s
imul d, s
#无符号数d*s,乘积存入d
#有符号数d*s,乘积存入d
dividediv s
idiv s
#无符号数除法:edx:eax/s,商存入eax,余数存入edx
#有符号数除法:edx:eax/s,商存入eax,余数存入edx
取负数negativeneg d#将d取负数,结果存入d
自增 ++increaseinc d#将d++,结果存入d
自减 - -decreasedec d#将d–,结果存入d

【注意】除法(被除数/除数)用到了隐含寻址,s是除数,而被除数提前放到了edx和eax。

【注意!】add d, s在这里是(d)+(s)→(d),

但是有的是写add s, d就是(d)+(s)→(d)

5.3.2逻辑运算
功能英文汇编指令注释
andand d, s#将d、s逐位相与,结果放回d
oror d, s#将d、s 逐位相或,结果放回d
notnot d#将d逐位取反,结果放回d
异或exclusive orxor d, s#将d、s逐位异或,结果放回d
左移shift leftshl d, s#将d逻辑左移s位,结果放回d(通常s是常量)
右移shift rightshr d, s#将d逻辑右移s位,结果放回d(通常s是常量)
5.3.3其他
  1. 用于实现分支结构、循环结构的指令:
    • cmp:比较。
    • test
    • jmp:直接跳转。
    • jxxx:条件跳转。
    • loop:封装循环。
  2. 用于实现函数调用的指令:
    • push:放入函数调用栈。
    • pop:从函数调用栈出栈。
    • call:函数调用。
      • ①将IP旧值压栈保存(保存在函数的栈帧顶部);
      • ②设置IP新值,无条件转移至被调用函数的第一条指令。
    • ret:函数返回。
      • 从函数的栈帧顶部找到IP旧值,将其出栈并恢复IP寄存器。
  3. 用于实现数据转移的指令:mov

【注意】Intel x86处理器中,程序计数器PC ( Program Counter)通常被称为IP(Instruction Pointer)。


5.4循环分支

5.4.1 jmp直接跳转指令

jmp(jump)

jmp <address>

jmp 124
jmp eax
jmp [985]

#其中:
exa = 124
[985] = 124

这个地址可以是直接一个数字,也可以是寄存器或者主存

但是其实程序员其实是不知道指令在内存的位置,所以使用**NEXT:标号**来锚定位置。

标号,有冒号就是,NEXT是名字,可以自己改)。

例如:

mov eax, 1
mov ebx, 2
jmp BIAOHAO
add ebx, 2
BIAOHAO:
add ebx, exa
5.4.2 jxxx条件跳转指令

先**比较cmp**两个数:

cmp本质上是进行a-b减法运算,并生成标志位OF、ZF、CF、SF,放入PSW程序状态字寄存器(Intel称其为“标志寄存器”)。

cmp d, s

然后紧跟跳转指令:

#jump when equal,若a==b则跳转
je <地址>

#jump when not equal,若a != b则跳转
jne <地址>

#jump when greater than,若a>b则跳转
jg <地址>

#jump when greater than or equal to,若a>=b则跳转
jge <地址>

#jump when less than,若a<b则跳转
jl <地址>

#jump when less than or equal to,若a<=b则跳转
jle <地址>
  • e:等于equal
  • n:不not
  • g:大于greater
  • l:小于less

例如:

cmp eax, ebx
je NEXT
分支C→汇编

那么就可以把c语言的代码翻译为汇编代码(机器级表示)

C:

int a=7;
int b=6;

if(a>b){
	c=a;
}else{
	c=b;
}

assembly:

mov eax,7		#假设变量a=7,存入eax
mov ebx,6		#假设变量b=6,存入ebx

cmp eax,ebx		#比较变量a和b
jg NEXT			#若a>b,转移到NEXT:

# 如果没有跳转,那么顺序执行,就是else

mov ecx ,ebx	#假设用ecx存储变量c,令c=b
jmp END			#无条件转移到END:
NEXT:
mov ecx ,eax	#假设用ecx存储变量c,令c=a
END:
循环C→汇编

用条件转移指令实现循环,需要4个部分构成:

①循环前的初始化

②是否直接跳过循环?

③循环主体

④是否继续循环?

在这里插入图片描述

用loop指令实现循环

【注意】loop默认使用ECX作为循环计数器(只能是ECX)。

在这里插入图片描述

5.5函数调用

函数的栈帧( Stack Frame):保存函数大括号内定义的局部变量、保存函数调用相关的信息。

在这里插入图片描述

5.5.1函数调用栈在内存中的位置

在这里插入图片描述

地址码中的堆栈寄存器(P,pointer)用于函数调用

  • EBP: 堆栈指针base pointer,指向栈的底部
  • ESP: 堆栈指针stack pointer ,指向栈的顶部(下面是“顶”,开口的)
5.5.2两种方式访问栈帧数据

pushpop指令实现入栈、出栈操作,x86默认以4字节为单位。指令格式如:

在这里插入图片描述

在这里插入图片描述

5.5.3函数调用时,如何切换栈帧

在每一个函数加上“例行处理”

push ebp		#保存上一层函数的栈帧基址(ebp旧值)
mov ebp, esp	#设置当前函数的栈帧基址(ebp新值)

#等价于:
enter			#零地址指令,进入

在函数结束的时候,就移除函数栈,例行处理:

mov esp, ebp	#让esp指向当前栈帧的底部
pop ebp			#将esp所指元素出栈,写入寄存器ebp

#等价于:
leave

在这里插入图片描述

5.5.4一个栈帧内可能包含哪些内容?

一个函数栈:

0xFFFF FFFF

栈底

EBP

向上(栈底)是加

向下(栈顶)是减

ESP

栈顶

0x0000 0000


  1. 上一层栈帧基址:栈帧最部一定是上一层栈帧基址(ebp旧值)。
  2. 返回地址:栈帧最部一定是返回地址(当前函数的栈帧除外)。
  3. 局部变量:保存在栈底,如果出现[ebp-4](最后一个定义的变量)或ebp-8这种,一般是局部变量。
  4. 调用参数:保存在栈顶[ebp+8](第一个调用参数),ebp+12(第二个调用参数)…。
    为什么是+8,因为+4保存了IP(PC)返回地址。这里的ebp不是上面的ebp,而是调用参数的ebp,属于上面函数的esp。
  5. 空闲:gcc编译器将每个栈帧大小设置为16B的整数倍(当前函数的栈帧除外),因此栈帧内可能出现空闲未使用的区域。

在这里插入图片描述

具体:

在这里插入图片描述

5.5.5如何传递参数和返回值

4.3_6_4_如何传递参数和返回值(函数调用的机器级表示)_哔哩哔哩_bilibili

相加之后,最终的结果存储在EAX,那么leave之后,caller函数只需要从EAX种就可以取到返回值。

在这里插入图片描述

总结

除了main函数,其他所有函数的汇编代码结构都一样!

在这里插入图片描述

5.6汇编格式

AT&T 格式:Unix、Linux的常用格式。

intel 格式:Windows的常用格式。(408常考,也是我们这里讲的

在这里插入图片描述

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

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

相关文章

Openstack 与 Ceph集群搭建(下): Openstack部署

文章目录 文章参考部署节点准备1. 修改Host文件与hostname名称2. 安装NTP软件3. 网卡配置信息4. 开启Docker共享挂载5. 安装python虚拟环境6. 安装kolla-ansible7. 加载Ansible galaxy requirements Openstack 安装前预配置1. 配置密码2. 配置multinode文件3. 修改全局配置文件…

2.Easy-Paas部署

目录 1.部署方式 2.docker-compose部署 1.1.准备docker环境 1.2.部署中间件 3.k8s部署 1.部署方式 docker-compose部署&#xff08;单节点&#xff09;k8s部署自研ops 2.docker-compose部署 1.1.准备docker环境 参考&#xff1a;二进制安装docker-CSDN博客 1.2.部署中…

安科瑞储能双向计量表DTSD1352-CT/CF 双向电量复费率统计

安科瑞徐赟杰 Hey科技迷们&#xff0c;你们是否对能源管理的新纪元充满好奇&#xff1f; 今天咱们来聊聊这款颠覆性的黑科技——安科瑞储能双向计量表DTSD1352&#xff01; 想象一下&#xff0c;一个能够掌控能量流动&#xff0c;无论是输入还是输出&#xff0c;都了如指掌的…

Thread类的基本用法(详解版)

什么是线程&#xff1f; 线程是操作系统能够进行调度的最小单位&#xff0c;通常被视为轻量级的进程。线程在同一进程中共享进程的资源&#xff08;如内存&#xff0c;打开的文件&#xff0c;网络等&#xff09;&#xff0c;但每一个线程都有自己的执行栈、程序计数器和局部变…

项目管理中什么是项目质量管理?

所有项目经理都易于犯下的通病便是产生无谓的乐观&#xff0c;误以为质量会自然而然地融入项目之中。然而&#xff0c;在实际操作中&#xff0c;我们必须明确界定、监控并管理项目管理质量。 项目质量管理的核心在于确保项目质量。这被称为项目的第四个约束&#xff0c;经理们必…

澄志创投马良骏:营销技术行业下一个关键词是合并与整合 | 中国广告营销行业资本报告深访①

日前&#xff0c;澄志创投发布了《中国广告营销行业资本报告2022》&#xff0c;投中信息提供独家数据支持&#xff0c;Marteker联合撰写。报告围绕广告营销行业的资本运作等话题&#xff0c;采访了行业资深人士。 马良骏Joshua&#xff08;澄志创投创始人&#xff09; 问&#…

Module not found: Can‘t resolve ‘tls‘/Module not found: Can‘t resolve ‘net‘

最近使用nextjs开发了一套系统&#xff0c;包含了前后端&#xff0c;但是前后端的界限其实没有那么清晰&#xff0c;很多地方都引入了公共的内容&#xff0c;甚至互相引入了其模块的内容 然后周五时在前端引入了一个方法&#xff08;该方法在前端的模块里面定义的&#xff0c;之…

【Linux】基本命令(第二篇)

目录 1.命令提示符 2.命令的基本格式 1) 选项的作用 2) 参数的作用 2.cd命令&#xff1a;切换目录 3.pwd命令&#xff1a;显示当前路径 4.ls命令&#xff1a;查看目录下文件 5.mkdir命令&#xff1a;创建目录&#xff08;文件夹&#xff09; 6.rmdir命令&#xff1a;删…

《黑神话:悟空》横空出世:全新国产3A里程碑之作

“直面天命”、“棒打虎先锋”、“猿神&#xff0c;启动”......在过去的一周里&#xff0c;从朋友圈到微博热搜&#xff0c;从咖啡联名到陕西文旅&#xff0c;几乎已经没有人&#xff0c;可以对《黑神话&#xff1a;悟空》这一国产3A里程碑之作视而不见。8月20日上午10时&…

eclipse汉化教程

1:选择HELP->install New software 2:点击Add 3&#xff1a;name随便填写&#xff0c;location&#xff1a;https://download.eclipse.org/technology/babel/update-site/latest/ 4&#xff1a;等待下载完成后点next 5&#xff1a;选择中文&#xff0c;再点击next 6. 等待…

【实战】Spring Boot 嵌套事务REQUIRES_NEW与NESTED在项目中的运用

文章目录 引言1. 什么是Nested Transactions?2. Spring Boot中的事务管理2.1 基本用法2.2 Nested Transactions的需求场景 3. 实现Nested Transactions3.1 使用Propagation.REQUIRED)/Propagation.NESTED)3.2 嵌套事务REQUIRES_NEW与NESTED3.3 注意事项 4. 测试Nested Transac…

upload-labs(Pass-18 ~ Pass-21)

1、Pass-18(条件竞争) 1、题目需要进行代码审计&#xff1a; <?php include ../config.php; include ../head.php; include ../menu.php;$is_upload false; $msg null;if(isset($_POST[submit])){$ext_arr array(jpg,png,gif);//白名单$file_name $_FILES[upload_fil…

OpenLayers3,地图探查功能实现

文章目录 一、前言二、代码实现三、总结 一、前言 图层探查&#xff0c;即对置于地图下方的图层进行一定范围的探查&#xff0c;以便用户查看到不易察觉的地理地况。本文基于OpenLayers3&#xff0c;实现地图探查的功能。 二、代码实现 <!DOCTYPE HTML PUBLIC "-//W…

滴滴拼车系统开发前景分析

滴滴拼车系统作为滴滴出行平台的一个重要组成部分&#xff0c;其开发前景分析如下&#xff1a; 市场需求&#xff1a;随着城市交通压力的增加和共享经济的普及&#xff0c;拼车服务因其便捷性和经济性受到越来越多用户的青睐&#xff0c;市场需求持续增长 。政策支持&#xf…

商业律师事务所借助 DocuSign 解决方案加快了 QES 和身份识别流程 | 电子签约律师事务解决方案

Roosbeh Karimi 是一位充满活力的年轻律师&#xff0c;他创办的商业律师事务所正引领着法律行业的数字化转型 KARIMI.legal 是一家总部位于柏林的商业律师事务所&#xff0c;专门从事商法、竞争法和法律技术集体诉讼。该商业律师事务所拥有一支由 11 名员工组成的团队&#xff…

音视频不同步问题总结

音视频同步的定义 指在视频播放过程中&#xff0c;图像和声音的播放时间保持一致&#xff0c;使得观众感觉到图像与声音是同时发生的。在实际的音视频 处理过程中&#xff0c;由于音频和视频的处理速度可能不同&#xff0c;或者由于网络传输的延迟&#xff0c;可能会导致音视…

地瓜直播间开播啦 | RDK X5-RWKV大模型部署实战

地瓜机器人新一代机器人开发者套件RDK X5&#xff0c;搭载旭日5智能计算方案&#xff0c;极简机器人开发体验&#xff0c;助力机器人开发一步通关&#xff08;更多产品信息请关注2024地瓜机器人开发者日暨新品发布活动&#xff0c;后续将在本公众号发布&#xff09;。 RWKV&…

零基础入门转录组数据分析——预后模型之lasso模型

零基础入门转录组数据分析——预后模型之lasso模型 目录 零基础入门转录组数据分析——预后模型之lasso模型1. 预后模型和lasso模型基础知识2. lasso预后模型&#xff08;Rstudio&#xff09;——代码实操2. 1 数据处理2. 2 构建lasso预后模型2. 3 提取Lasso预后基因2. 4 计算风…

Java框架myBatis(三)

一、特殊符号转义 特殊符号处理 在mybatis中的xml文件中&#xff0c;存在一些特殊的符号&#xff0c;比如&#xff1a;、"、&、<> 等&#xff0c;正常书写mybatis会报错&#xff0c;需要对这些符号进行转义。 具体转义如下所示&#xff1a; 特殊字符 转义字符…

图解 Elasticsearch 的 Fielddata Cache 使用与优化

1、难搞的 fielddata cache 在 ES 使用的几个内存缓存中&#xff0c;fielddata cache 算是一个让人头疼的家伙。 作为和 query cache 和 request cache 一样不受 GC 控制的内存使用者&#xff0c;fielddata cache 虽然也有 indices.fielddata.cache.size 的设置来阻止过度使用&…