汇编入门

网友投稿 857 2022-05-29

一、基础知识

( 1 )机器语言

机器语言是机器指令的集合。电子计算机的机器指令是一系列二进制数字。计算机将之转换为一系列高低电平脉冲信号来驱动硬件工作的。

(2)汇编语言的产生

我们知道机器只能看懂机器语言,也就是0和1。实际上0和1只是我们规定的数字,机器其实连0和1也看不懂,这里的0和1实际上是指两种不同的电压状态,计算机是用电的,它能理解的就是电压的变化,所以我们通过不同的电压驱动计算机运算,来完成我们所需要的任务。

在早期,人们通过纸带来编程,打孔的地方表示1, 不 打孔的地方表示0,然后将纸带输入计算机中。这种方式不但费时费力,而且不同发现错误。

例如下面的程序:

-

Java 代码

1

101110000000000000000011

2

000001010000000000110000

3

001011010000000000000101

这是8086CPU完成运算s=768+12288-1280的程序,如果这个程序中错误的将一个0写成了1,试想要想发现这个错误是多么的困难。

为了方便人们编写程序,并且避免01代码容易出错的问题,人们发明了汇编语言。

例如:机器指令1000100111011000表示把寄存器BX的内容送到AX中。汇编指令则写成 mov ax,bx 。这样的写法与人类语言接近,便于阅读和记忆。

(3)汇编语言的组成

汇编指令 ( 机器码的助记符,有对应的机器码 ) ;

伪指令 ( 由编译器执行 ) 和 其他符号 ( 由编译器识别 ) 。

(4) 存储器

CPU工作需要指令和数据,指令和数据存储在存储器中。

(5)指令和数据

在内存或者磁盘中存储的都是为二进制信息, 指令和数据由我们设定(走的总线) 。

(6) 存储单元

• 存储器被划分为若干个存储单元,每个存储单元从0开始顺序编号。

• B、KB、MB、GB、TB等单位。

(7)CPU对存储器的读写

我们知道数据和指令是放在内存中的,CPU通过总线对存储器进行访问,但实际上总线是分为三部分的,即地址线,控制线和数据线。地址线表示CPU要对内存中的哪个地址进行操作,所以地址线的条数决定了CPU能够访问的内存范围,因为一根线上最多只能有两种不同的状态即0和1,所以10根地址线能够访问的存储单元的个数就是2^10个。

地址 线仅仅 是送出了要操作的地址,但是并没有声明要进行什么操作,所以控制线就是来决定对存储单元的操作的。所以说控制线的条数决定了CPU能够执行的操作的种类。

数据线是用来在CPU和内存之间进行数据传送的,所以数据线的条数决定了一次最多传送的数据的数量,例如8根数据线一次就能传送8个bit即一个字节。

上图展示了CPU从3号内存单元中读取数据的过程。首先CPU利用数据线送出地址3,然后通过控制线发送读命令,然后内存将结果通过数据线返回给CPU。

(8) 内存地址空间

什么是内存地址空间呢?举例来讲,一个CPU的地址总线宽度为10,那么可以寻址1024个内存单元,这1024个可寻到的内存单元就构成了这个CPU的内存地址空间。当然这里所说的内存并不单单是内存条中的内存,还包括其他各种外设中的RAM和ROM。例如,显卡也有自己的内存,用来存储在显示屏上显示的内容,另外显卡BIOS ROM也被 当做 是内存空间中的一部分,此外还有网卡的BIOS ROM和系统BIOS ROM地址空间等。

因此我们在基于一个计算机硬件系统编程时,必须要知道这个系统中的内存地址空间分配情况。应为当我们想在某类存储器中读写数据的时候,必须知道它的第一个单元地址和最后一个单元地址,才能保证读写操作是在预期的存储器中进行的。比如,我们希望在显示器上输出一段信息,那么必须将这段信息写到显存中,显卡才能将它输出到显示器上,要想向显存中写入数据,必须知道 显存在 地址空间中的地址。

上图展示了8086PC机内存地址空间分配的基本情况。从地址0~9FFFF的内存单元中读取数据,实际上就是在 读取住 随机存储器中的数据;向地址A0000~BFFFF的内存单元中写数据,就是向显示器中写入数据,这些数据 会被显卡 显示到显示器上;我们向C0000~FFFFFF的内存单元中写入数据的操作是无效的,因为这等于改写只读存储器中的内容。

小结:

1、汇编指令时机器指令的助记符,与机器指令一一对应。

2、每一种CPU都有自己的汇编指令集。

3、CPU可以直接使用的信息在存储器中存放。

4、在存储器中指令和数据都是二进制信息。

5、存储单元从0开始顺序编号。

6、一个存储单元可以存储8个bit。

7、B、KB、MB、GB等单位之间的转换。

8、CPU管脚和总线相连。总线的宽度表示CPU不同方面的性能:

(1)地址总线的宽度决定了CPU的寻址能力;

(2)数据总线的宽度决定了CPU与其他器件进行一次数据传送的量;

(3)控制总线宽度决定了CPU对系统中其他器件的控制。

二、寄存器(CPU的工作原理)

CPU由运算器、控制器、寄存器 等器件组成,靠内部总线相连。

内部总线实现CPU内部各器件之间的联系;外部总线实现CPU和主板上其他器件的联系。

在CPU中:

(1)运算器进行信息处理;

(2)寄存器进行信息存储;

(3)控制器控制各种器件进行工作;

(4)内部总线连接各种器件在它们之间进行数据的传送。

1、 通用寄存器

8086有14个寄存器:

AX、BX、CX、DX、SI、DI、SP、BP、IP、CS、SS、CS、ES、PSW。

AX、BX、CX、DX通常用来存放一般性数据,被称为通用寄存器。

16位寄存器所能存储的数据最大值为2^16-1 。

为保证兼容性,8086 CPU的通用寄存器可以分为两个独立的8位寄存器使用。例: AX可分为AH和AL。

2、 字在寄存器中的存储

(1)8086 CPU所有的寄存器是16位,可以存放2个字节(一个字)

(2) 一 字节由8 bit 组成,可以存在8位寄存器中

(3)字(word)是两字节,16位。

3、几条汇编指令

汇编指令对大小写不敏感

4、 物理地址

• 所有的内存单元构成一个一维的线性存储空间。

• CPU访问内存单元时要给出内存单元的唯一地址就是物理地址。

5、16位结构的CPU

• 运算器一次最多可以处理16位数据。

汇编入门

• 寄存器的最大宽度为16位。

• 寄存器和运算器之间的通路是16位。

6、 8086 CPU给出物理地址的方法

• 8086有20位的地址总线,可以传送20位地址,寻址能力为1M;但8086内部为16位结构,只能传送16位的地址。

• 8086CPU采用一种在内部用两个16位地址合成的方法来形成一个20位的物理地址。

8086CPU读写内存的步骤:

(1)CPU中的相关部件提供段子和偏移地址这两个16位的地址;

(2)段地址和偏移地址通过内部总线送入到一个称为地址加法器的部件;

(3)地址加法器将两个16位地址合并成一个20位的地址;

(4)地址加法器通过内部总线将20位物理地址 送 送入输入输出地址;

(5)输入输出控制电路将20位物理地址送上地址总线;

(6)20位物理地址被地址总线传送到存储器。

地址加法器工作原理:物理地址=段地址*16+偏移地址。

段地址*16就是数据左移4位(二进制)

一个数据的二进制形式左移N位,相当于该数据乘以2的N次方。一个数据X进制形式左移N位,相当乘以N^X。

7、段地址*16+偏移地址=物理地址

CPU可以通过不同的段地址和偏移地址形成一个相同的物理地址。

8、段的概念

人为定义的,将若干地址连续的内存单元看作一个段。用段地址*16定位段的起始地址(基址),用偏移地址定位段中的内存单元。

一个段的起始地址是16的倍数。偏移地址为16位,寻址能力为64K,所以段的最大长度也是64K

三、寄存器(内存访问)

1、 mov 、add、sub指令

• 有两个操作对象, jmp 只有一个操作对象。

• 使用 汇编金 手指查阅指令

• mov 指令的几种形式

-

Java 代码

1

mov 寄存器,数据;             mov ax,8

2

mov 寄存器,寄存器;          mov ax,bx

3

mov 寄存器,内存单元;      mov ax,[0]

4

mov 内存单元,寄存器;      mov [0],ax

5

mov 段寄存器,寄存器;      mov ds,ax

6

mov 寄存器,段寄存器;      mov ax,ds

• add指令的几种形式

-

Java 代码

1

add 通用寄存器,数据

2

add 通用寄存器,通用寄存器

3

add 通用寄存器,内存单元

4

add 内存单元,寄存器

• sub指令的几种形式

-

Java 代码

1

sub 通用寄存器,数据

2

sub 通用寄存器,通用寄存器

3

sub 通用寄存器,内存单元

4

sub 内存单元,通用寄存器 

2、 栈

• 具有特殊的访问方式的存储空间,也是内存空间的一部分,数据 先进后出。

• 有两个基本操作:

o 入 栈 :将一个新的元素放到 栈 顶;

o 出 栈 :从 栈 顶取出一个元素。

• 栈 顶元素最后入 栈 最先出 栈 。

3、8086 CPU提供的 栈 机制

现今的CPU都有 栈 的设计,基于8086CPU编程可以将一段内存当作 栈 来使用。

8086CPU的入 栈 (PUSH)和POP(出 栈 ),以字为单位。

push ax 将寄存器ax中的数据送入 栈

pop ax 从 栈 顶取出数据送入ax

段寄存器SS存放 栈 顶的段地址,寄存器SP存放 栈 顶的偏移地址。任意时刻SS:SP指向 栈 顶元素。push时SP先自减法后写内存,pop先读内存 sp 后自加。

pop之后数据还是存在内存中,push时覆盖。

CS和IP存放当前指令的段地址和偏移地址。

4、 栈 顶越界的问题

• 栈 是空的,则SP指向 栈 底+1的内存。

• 8086 CPU只纪录 栈 顶, 栈 空间由自己控制。 栈 顶越界问题导致溢出漏洞。

• 8086CPU只考虑当前的情况:

o 当前 栈 顶在何处;

o 当前要执行的指令时哪一条。

汇编语言

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:C语言的20条编程核心知识要点
下一篇:如何在二三线城市月薪过万(八)做好职业规划,做一个平凡而不平庸的自己
相关文章