淘姐妹

淘姐妹

为什么要学习汇编语言呢?

电脑 0

淘宝搜:【天降红包222】领超级红包,京东搜:【天降红包222】
淘宝互助,淘宝双11微信互助群关注公众号 【淘姐妹】

为什么很少人学汇编,汇编语言为什么叫汇编,汇编语言为什么这么难,学好汇编语言有什么用
  • 汇编笔记
    • 为什么要学习汇编语言呢?
    • 什么是汇编语言?
    • 字节长度问题
    • 补充基础知识
      • 地址总线
      • 控制总线
      • 数据总线
      • 存储器的分类(ROM / RAM)
    • 寄存器
      • 数据寄存器
      • 指针寄存器
      • 变址寄存器
      • 指令指针寄存器
      • 标志寄存器
      • 段寄存器
      • 寄存器寻址
    • CPU指令
      • 数据传送指令(MOV)
      • 加减运算指令
      • 逻辑运算(按2进制进行位运算)
      • MOV、LEA指令
    • 移位指令
    • TEST,CMP指令
    • PUSH,POP指令
    • AMP,NOP指令
    • JCC指令
    • CALL,RETN指令
  • 深入理解计算机系统
    • 第一章 计算机系统漫游
      • 1.1 信息 = 位 + 上下文
      • 1.2 程序被其他程序翻译成不同的格式
      • 1.3 了解编译系统如何工作是大有益处的
      • 1.4 处理器读并解释存储在内存中的指令
        • 1.4.1 系统的硬件组成
        • 1.4.2 运行hello程序
      • 1.5 高速缓存至关重要
      • 1.6 存储设备形成层次结构
      • 1.7 操作系统管理硬件
        • 1.7.1 进程
        • 1.7.1 线程
        • 1.7.3 虚拟内存
        • 1.7.4 文件
      • 1.8 系统之间利用网络通信
      • 1.9 重要主题
        • 1.9.1 Amdahl定律
        • 1.9.2 并发和并行
学习目标: 看懂汇编指令、会写一部分汇编指令

基础知识: 计算机组成原理

汇编语言,是除了机器语言外的最底层的编程语言了。学习这门语言,可以帮助我们更加深入地理解CPU、内存等硬件的工作原理。用机器的思维去操作计算机。汇编语言和机器语言是一一对应的,汇编语言被编译成机器语言,这样的程序执行效率更高。

汇编语言是直接在硬件之上工作的编程语言,学习汇编语言之前最好先了解一下计算机硬件系统的结构和工作原理。学习汇编语言的重点是学习如何利用硬件系统的编程结构和指令集进而有效地灵活地控制系统执行工作。

8 bit(位) = 1 Byte(字节) 1024 Byte(字节) = 1 KB 1024 KB = 1 MB 1024MB = 1G

字: 计算机中,一串数码作为一个整体来处理或运算,这串数码成为计算机字.通常每个字分为若干个字节. 字长: 计算机中每个字包含的位数称为字长

32位操作系统是指该操作系统每个字长度为32位(4个字节/32个位) 00 00 00 0F = 00000000 00000000 00000000 00001111 32位寄存器,4个字节,8个数字,每2个数字构成1字节,2字节构成1个字

CPU是通过地址总线来寻找和指定存储单元的,地址总线上能传输多少个不同的地址信息,那么CPU就可以对多少个存储单元进行寻址。如果一个CPU有 N 根地址总线,则可以说这个CPU的地址总线宽度即为N,那么这个CPU最多可以寻找到 2 的N次方个存储单元。地址总线的宽度,决定了CPU的寻址能力。

CPU对外部器件的控制是通过控制总线来实现的。控制总线是一些不同类型的控制线的集合。理论上讲,有多少根控制总线,就意味着CPU能提供对外器件的多少种控制。这里所说的控制,无非就是读和写两种,对一根控制线来讲,发送0表示读(低电平),发送1表示写(高电平)。有多少根控制线,就能控制多少个外部器件。控制总线的宽度,决定了CPU对外部器件的控制能力。

CPU与存储器之间的数据信息传输是通过数据总线来完成的。数据总线的宽度决定了CPU和外界的数据传输速度。可以把数据总线类比成高速公路,路面上的车道数越多,则通车的速度就更快。举例说明,8088CPU的数据总线宽度是8位(即有8根数据总线),如果它要把 8D99H 这个数据传递至存储器,则需要传递两次,先把低位 99 传递过去,再把高位的 8D 传递过去;如果是 8086CPU,则只需要一次传递即可把 8D99H 传递至存储器,因为 8086CPU 的数据总线宽度是 16 位(即有16根数据总线)的。数据总线的宽度,是决定CPU运算速度的因素之一(当今的CPU之所以工作速度越来越快,这不仅仅与数据总线宽度越来越宽有关,还与寄存器、二级缓存数量的增加有关,还与“打孔->计电器->电子管->晶体管”的技术发展有关)。

从读写属性上划分,可以分为随机存储器(RAM)和只读存储器(ROM)。随机存储器中的数据可读可写,当电脑断电时数据会丢失,比如内存;只读存储器只能读数据,不能写入数据,电脑断电后数据不会丢失,这些数据是硬件设计者预先写入的,比如BIOS的ROM。 从功能和连接类型上划分,可以分为常用RAM,接口卡的RAM,接口卡上的ROM。

保存操作数,计算结果

EAX(Accumulator): 累加寄存器,也称累加器.

EBX(Base): 基地址寄存器,也称基址寄存器,DS段的数据指针.

ECX(Count): 计数器寄存器.

EDX(Data): 数据寄存器,I/O指针.

32位寄存器: EAX,EBX,ECX,EDX

16位寄存器:AX,BX,CX,DX

低八位: al

高八位: ah

操作栈的寄存器

栈: 参数,变量

EBP: 栈底指针

ESP: 栈顶指针

ESI和EDI: 用来存放地址的寄存器

ESI: 指向原始偏移地址,字符串操作的源指针

EDI: 指向目标偏移地址,字符串操作的目标指针

EIP: cup下次将要执行的代码的地址

又叫flag寄存器 16位

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WKlxZgHq-【【QQ微信】】73)(汇编笔记.assets/70.jpeg)]

PF(parity flag):奇偶标志位。这个位的判断需要我们将结果转为二进制来看,如果结果的低8位中有偶数个1,就将PF的值置1;如果是奇数个1,就置0。要注意的是一定是结果的低8位。

AF(auxiliary flag):辅助进位标志位。这个位用的不多,所以书上也没有讲,我就简单的查了一下资料。这个位表示加减法做到一半时有没有形成进位/借位,如果有则AF=1。这么说谁都听不懂,所以我们举个例子来说下。例如 MOV AL,00001110 MOV BL,00001000 ADD AL,BL 最后结果为AL=00010110这就是低四位向高四位进位。反之在减法中第三位不够减向第四位借位(注意数位是从第0位开始数的)叫低四位向高四位借位!像前面的AL中前四位为高四位,后四位为低四位。例如,当两个字节相加时,如果从低4位向高4位有进位时,则AF=1。

ZF(zero flag):零标志位。这个位就很简单了,判断结果是不是0。如果结果为0,就置1;不为0,就置0。

SF(sign flag):符号标志位。既然是符号标志位,就是对有符号数据来说的。如果结果为负,就置1;结果为正,就置0。

TF(timer o【【微信】】):定时器溢出标志。这个位主要是用来在debug中进行-t指令时使用的。当cpu在执行完一条指令后,如果检测到TF位的值为1,则产生单步中断,引发中断过程。通过这个位,我们就可以在debug中对程序进行单步跟踪。

IF(interrupt flag):中断允许标志位。当IF=1时,cpu在执行完当前指令后响应中断,引发中断过程;当IF=0时,则不响应可屏蔽中断。

DF(direction flag):方向标志位。在串处理指令中,控制每次操作后,si(指向原始偏移地址)、di(指向目标偏移地址)的增减。当DF=0时,每次操作后,si、di递增;DF=1时,每次操作后,si、di递减。我们可以使用cld指令将DF的值置为0,使用std指令将DF的值置为1。DF需要与rep、movsb等指令配合使用。

OF(o【【微信】】):溢出标志位。这个位是用来判断有没有溢出的。注意溢出这个概念只对于有符号数据而言,就如同进位只对于无符号数据而言。当OF=0时,说明没有溢出;当OF=1时,说明溢出了。

段寄存器是因为对内存的分段管理而设置的。8086 CPU有4个段寄存器: CS、DS、SS、ES,当8086CPU要访问内存时,由这4个段寄存器提供内存单元的段地址.

1、取指令: 段寄存器CS指向存放程序的内存段,IP是用来存放下条待执行命令在该段的偏移量.把它们合在一起可在该内存段内取到下次要执行的指令。

2、取堆栈: 段寄存器SS指向用于堆栈的内存段,SP是用来指向堆栈的栈顶,把他们合在一起可访问栈顶单元.另外,当偏移量用到了指针寄存器BP,则其缺省的段寄存器也是SS,并且用BP可访问整个堆栈,不仅仅是只访问栈顶。另外,当偏移量用到了指针寄存器BP,则其缺省的段寄存器也是SS,并且用BP可访问整个堆栈,不仅仅是只访问栈顶。

3、段寄存器DS指向数据段,ES指向附加段,在存取操作数时,二者之一和一个偏移量合并就可得到存储单元的物理地址。该偏移量可以是具体数值、符号地址和指针寄存器的值等之一,具体情况将由指令的寻址方式来决定。通常,缺省的数据段寄存器是DS,只有一个例外,即:在进行串操作时,其目的地址的段寄存器规定为ES。

4、其它情况,段寄存器除了其默认引用的寄存器外,还可以强行改变为其它段寄存器。

1、立即寻址(操作数作为指令的一部分而直接写在指令中,这种操作数成为立即数)

MOV AH, 80H

ADD AX, 123H

2、寄存器寻址(指令所要的操作数已存储在某寄存器中,或把目标操作数存入寄存器)

ADD VARD, EAX ##源操作数是寄存器寻址方式

ADD BH, 78h ## 目的操作数是寄存器寻址方式

MOV EAX, EBX ## 源和目的操作数都是寄存器寻址方式

3、直接寻址(指令所要的操作数存放在内存中,在指令中直接给出该操作数的有效地址)

MOV BX, [1234H] ## 在执行时,(DS)=2000H,内存单元21234H值为5213H

执行步骤介绍: 1). 由于1234H时一个直接地址,它紧跟在指令的操作码之后,随取指令而被读出; 2).访问数据段的段琪存起是DS,所以,用DS的值(左移4位)和偏移量1234H相加,得存储单元的物理地址: 21234H; 3).取出21234H的值为5213H,并按“高高低低”的原则存入寄存器BX中.

MOV ES:[1000H], AX ## 认为DS,如果要指定访问其他段内的数据,可在指令中用段前缀的方式显式的书写出来.

4、寄存器间接寻址(用SI、DI和BX等之一来指定,则其缺省的段寄存器为DS;用BP来指定,则其缺省的段寄存器为SS)

MOV BX,[DI], 在执行时,(DS)=10000H, (DI)=2345H,存储单元12345H的内容是4354H.

执行结果: PA=(DS) * 16+DI=1000H * 16+2345H=12345H ## 该指令的执行效果是: 把从物理地址为12345H开始的一个字的值传给BX.

5、寄存器相对寻址(同上,但增加一个偏移量)

MOV BX,[SI+100H] ## 在执行它时,(DS)=1000H,(SI)=2345H,内存单元12445H的内容为2715H EA=(SI)+100H=2345H+100H=2445H PA=(DS)* 16+EA=1000H* 16+2445H=12445H

指令效果: 把从物理地址为12111H开始的一个字的值传送给BX

6、基址加变址寻址方式(有效地址时一个基址寄存器(BX、BP)和一个变址寄存器(SI、DI)的内容之和)

MOV BX,[BX+SI] ## 在执行时,(DS)=1000H,(BX)=2100H,(SI)=0011H,内存单元12111H的内容时1234H

EA=(BX) + (SI) = 2100H + 0011H = 2111H

PA=(BX)* 16 + EA = 10000H + 2111H = 12111H

指令效果: 把从物理地址为12111H开始的一个字的值传送给BX

7、相对基址加变址寻址方式(同上,但增加一个偏移量)

MOV AX,[BX+SI+200H] ## 在执行时,(DS)=1000H,(BX)=2100H,(SI)=0010H,内存单元12310H的内容为1234H

EA=(BX)+(SI)+200H=2100H+0010H+200H=2310H

PA=(DS)16+EA=1000H16+2310H=12310H

指令效果: 把从物理地址为12310H开始的一个字的值传送给AX

下面四种书写方式等价:

MOV AX,[BX+SI+1000H]

MOV AX,1000H[BX+SI]

MOV AX,1000H[BX][SI]

MOV AX,1000H[SI][BX]

mov ax,bx ## 将bx指向的地址存储的值传递给ax

add eax, 8 // a= 8+ 0

sub eax, 5 // a = eax - 5

逻辑与: and 有0为9,全1为1

逻辑或: or 有1为1,全0为0

逻辑异或: xor 同为1,异为0

逻辑非: not

LEA: load effecti【【微信】】, 加载有效地址,可以将有效地址传送到指定的的寄存器。指令形式是从存储器读数据到寄存器, 效果是将存储器的有效地址写入到目的操作数, 简单说, 就是C语言中的”&”.

MOV: 在CPU内或CPU和存储器之间传送字或字节,它传送的信息可以从寄存器到寄存器,立即数到寄存器,立即数到存储单元,从存储单元到寄存器,从寄存器到存储单元,从寄存器或存储单元到除CS外的段寄存器(注意立即数不能直接送段寄存器),从段寄存器到寄存器或存储单元。

使用[]的区别: 第二操作数加不加中括号[]的区别就是: lea对变量没有影响是取地址,对寄存器来说加[]时取值,第二操作数不加[]非法 mov对变量来说没有影响是取值,对寄存器来说是加[]时取地址,第二操作数不加[]是取值

算数左移: sal 所有数左移一位,最低位补0,最高位写入CF标志位.

算数右移: sar 所有数右移一位,最高位保持不变,最低位写入CF标志位.

逻辑左移: shl 同算数左移一直.

逻辑右移: shr 所有数右移,最高位补零,最低位写入CF标志位.

test指令: 与and指令一致,但不会改变寄存器内的值,当结果为0时,会将ZF标志位修改为1,当test指令执行结果不为0时,Z标志位修改为0

cmp指令: 与sub指令一致,但不会改变寄存器内的值,当结果为0时,会将ZF标志位修改为1,当test指令执行结果不为0时,Z标志位修改为0

push和pop都是操作堆栈的指令

push是压栈指令,pop是出栈指令

push指令: 1、栈顶地址减4 2、将数值压栈

pop指令:

1、栈顶数据出栈 2、栈顶地址加4

jmp指令: 无条件跳转指令 nop指令: 空指令(cpu执行到这个命令什么都不执行)

jcc指令: 条件跳转

call指令: jump + 将下一步指令地址压入栈内

retn指令: 从栈顶取出地址数据 + jump

先说一下位,计算机的最小单位,一个位可以取两个值1/0(高电平/低电平)代表两种状态(1个位=1bit).

但是世界事物千千万,无法用一个位来表示,怎么办呢? 某不知名人士说过,没有什么东西是0和1无法表示的,如果有…那就再加一个0和1.所以,在计算机中,一般由8位表示一组(即8bit=1byte, 1字节=1byte),而这一组可以表示2的8次方个字符(字母、符号或者数字),而这256个字符就构成了计算机系统的基础.

最早ascii是7位,后来欧洲那帮货给拓展到了8位,现在为了兼容其他国家给拓展的更多了,我这边理解一律按照8位.

下面来看一个简单的例子:

这是每个计算机系学生的编程第一课,每个程序员无论你现在使用的是什么语言,无论是C、C++、java、【【微信】】、go、ruby或者其他,相信对helloWorld都不陌生,但是你知道从计算机的角度来看,这段代码是什么样子的吗?

让我们再深一步的观察一下这段代码的ASCII表示方法:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-【【微信】】【【QQ微信】】74)(汇编笔记.assets/image-20200116150247530.png)]

SP: space空格 : 换行

那么看到这里是不是可以从这两个方向理解这段代码(实际上要比这复杂的多): 程序员视角: 代码(由字符串组成) --> byte(与ascii码一一对应) --> 一段连续的位符号

计算机视角: 一段连续的位符号 --> byte(与ascii码一一对应) --> 代码(由字符串组成)

其中如何将这一个个字符串分割、组合,依靠的就是上下文.

再来介绍上下文(Context),上下文对于我来说一直是一个充满玄学的词汇,也不知道谁提出的.在不通场景下,上下文代表不同的东西,如果要简单的理解的话,上下文就是环境、就是一段代码执行所需要的条件.下面这段是摘自Quora内的回答:

【【微信】】 "it depends on the context”(跟我说的差不多一个意思)

Context is the background information we need to understand the “unit of understanding” that we’re currently looking at. Ideally it would tell us in a straight-forward way what the assumptions and decisions that led to this point were.<

为什么电脑老是卡死


展开全部

电脑卡顿常见的原因可能包括以下几个方面:

  • CPU性能不足:电脑的CPU处理器如果太老旧或配置较低,会导致运行和处理速度缓慢,从而出现卡顿、停滞等问题。

  • 内存不足:内存(Memory)是计算机程序运行必要的组件之一。在多任务处理时,当运行的软件需要的内存资源超过了计算机可用的物理内存,系统就会把部分数据写入硬盘,这种交换式储存容易导致电脑卡顿甚至死机。

  • 磁盘空间不足:计算机磁盘空间不足时,往往会导致应用崩溃、卡顿、操作受阻等现象。

  • 计算机病毒或恶意软件:如果发现计算机出现频繁的卡顿和其他异常行为,可能电脑中感染了病毒或恶意软件。

  • 系统或软件故障:计算机系统出现故障或者运行的软件存在bug时,都可能导致电脑卡顿。

  • 运行多余程序:如果同时运行过多的程序,很容易让计算机的纷繁运行产生资源竞争、卡顿等问题。

  • 为了解决电脑卡顿问题,可以尝试以下措施:

  • 清理系统垃圾:清理系统垃圾和无用文件能够释放磁盘空间,提高计算机硬盘运行效率。

  • 增加电脑内存:增加内存可有效缓解内存不足的情况,在装机或者升级时选择大容量内存内容对于日常使用应该开足够。

  • 卸载并升级过期程序:卸载长时间未使用的软件和更新陈旧的程序有利于解决卡顿问题。

  • 安装杀毒软件查杀病毒: 可下载安装主流杀毒软件对计算机进行全面扫描和保护。

  • 关闭多余进程:关闭一些后台运行的应用以及多余的进程、浏览器标签页,能有效节省计算机运行所需的资源。

  • 对操作系统进行优化:调整系统设置,关闭视觉效果或服务、减少启动项等,可能帮助解决电脑卡顿问题。

  • 如果自己操作还是不得要领,建议寻找相关专业人员帮忙诊断故障并排除。