计算机什么时候学汇编,[计算机基础] 汇编学习(1)

一、汇编环境准备

1.安装DOSbox

安装完毕后,配置一个根目录,修改以下配置文件:

C:UsersAdministratorAppDataLocalDOSBoxdosbox-0.74-3.conf

最后部分修改为:

[autoexec]

# Linesinthis section will be run at startup.

# You can put your MOUNT lines here.mountc: d:asm

c:

d:asm是我们的工作目录。

2.准备工具

将以下工具都放到工作目录下:

debug.exe

masm.exe

link.exe

二、初识汇编

1.汇编器(汇编编译器)和指令

机器指令:0101001110

汇编指令:MOV AX,000C   人类能识别和编写的指令

汇编器:将汇编指令翻译成机器指令的翻译器。即可以将MOV AX,000C翻译成0110110011这种二进制机器码。

在DOSBOX中输入debug -u,可以看到以下内容:

746fe952f094f178609a1dd06d253d79.png

左边的16进制数据和右边的汇编指令是对等的。即汇编器将右边的汇编指令翻译成了左边的16进制(对应二进制机器码)。

最左边的 073F:0100 是内存编号,他们是连续的,最小单位是byte,所以 74 03 这个指令占2个byte。

在我们使用 debug -u 的时候,该指令将内存中的数据解析成指令,我们也可以使用 debug -d 来查看内存中的原始数据:

bb3dbf605af1ead9b386483d52f3686e.png

可以看到, 073F:0100 开始的内存数据和上一个图中指令对应数据是一致的,只是 -d 指令将其显示为普通数据而已( -u 指令解析为指令)。

三、一些概念

1.地址线

CPU从内存读取数据的时候,要告诉内存我要拿那个地址的数据。由于CPU是通过电信号来传递地址信息的,电信号只有高低电平,也就是0和1。

如果地址线只有一条路,则只能表示2个位置,一个是0,一个是1。

如果地址线有两条路,则可以表示4个位置,00、01、10、11。

如果地址线有三条路,则可以表示8个位置,000、001、010、011、100、101、110、111。

以此类推:

我们所说的32位和64位表示的就是地址线的宽度,也就是地址线有多少个通路。32位就表示用32个二进制来表示内存地址,所以能够发给内存的地址信息是0~232-1,即0~4,294,967,295,这也就是说32位地址的内存有232个格子,每个格子为1 byte,这也就是为什么32位系统只能支持4G内存(4G内存就是232byte)。

在以往的CPU型号中,地址线的数量如下:

8080:16根,寻址能力为64KB8088:20根,寻址能力为1MB80286:24根,寻址能力为16MB80386:32根,寻址能力为4GB

2.数据线

与地址线类似,地址线传送的数据用来表示内存位置,而数据线就是传递的数据本身。

假设数据线有8个通道,每一个通道传递一个二进制,则8个通道一次性就可以传递一个byte的数据。

如果有16个通道,则一次性可以传递两个byte的数据。

以此类推

以往CPU支持数据线的数量:

8080:8根,一次传递一个byte8088:8根,一次传递一个byte8086:16根,一次传递两个byte80286:16根,一次传递两个byte80386:32根,一次传递四个byte

3.控制线

控制线决定了CPU对其他部件(很多部件)进行控制的能力。

4.外部设备

除了内存、显存、ROM等设备的数据是通过内存地址去访问。还有一些外部设备,例如键盘、鼠标等是通过port端口号去访问的。

我们拆开鼠标或键盘可以看到这些设备都有一个芯片。

这个芯片中也会有一个存储空间,当我们按下一个键时,对应的数据会存储在该芯片的空间中。

然后通过线缆传递到主板的一个端口,然后CPU再通过端口号读取对应端口的数据,从而实现CPU读取外设数据。

四、寄存器

1.什么是寄存器

寄存器就是CPU用来存放指令和数据的地方,通过 debug -r 可以查看:

b227ddfea8b77314981729998ff55201.png

2.AX、BX、CX、DX寄存器

这四个寄存器就做通用寄存器,用于存储数据。每个寄存器可以存储2byte大小的数据,即16bit。

这四个寄存器有个特殊的地方,就是可以分为两个8bit的寄存器:

AX = AH +AL

BX= BH +BL

CX= CH +CL

DX= DH + DL

H代表高八位,L代表低八位。

例如8086 CPU的数据线为16bit,则一次性最大可以读取2byte的数据,也就是说可以处理两种尺寸的数据:

字节型数据  1byte放在8位寄存器中

字型数据   2byte  放在16位寄存器中

我们也可以称一个寄存器中,一个字节是这个字型数据的高位字节,另一个字节是这个字型数据的低位字节。

使用 debug -a 来体验一下给寄存器赋值:

3bb74d9126b4add10eeb4a34f66686f1.png

注意,由于我们使用mov给AX寄存器赋值,AX寄存器为16bit寄存器,所以5被翻译成了0005H。

当我们对8bit寄存器赋值时,如下所示:

d7c28e49c68fdc24a796c8cb35df6943.png

可以看到,mov中的8被翻译成了08H。而且值被赋予到了AH 8位寄存器中。

我们也可以同时输入多条指令,然后一条条执行:

a472981060cb7981b8f4a25e24870a6d.png

注意:数据大小与寄存器大小必须保证一致性,即8bit寄存器存放8bit数据,16bit寄存器存放16bit数据,否则会报错。

3.寄存器的独立性

寄存器是相互独立,互不影响的,就算是一个16位寄存器分成的H和L两个8位寄存器,也是互不影响的。

例如,我们执行8bit 的加法运算:

62e007c0074ff327576162e666b8e9d1.png

至于溢出的部分数据,保存在了其他地方。

4.地址寄存器

前面了解的AX、BX、CX、DX都是用于存储数据的通用寄存器。这节我们了解一下存放内存地址的寄存器。

使用 debug -u 查看内存地址时,我们可以看到两列地址信息:

5b3bca6f4c0f58692d88ed8d81da3e4d.png

其中左边部分为段地址,右边部分为偏移地址部分。这两部分分别都是16bit大小,也就是都需要一个16bit寄存器来存储。

为什么要将内存地址分为两部分?

这是因为我们提高寻址能力就是要加宽地址线的数量,例如8086CPU的地址线为20bit,那么一个寄存器已经无法满足存储这个地址信息。

于是就使用了段地址+偏移地址的形式,公式如下:

基础地址 = 段地址 *10H # 例如段地址为F230H,向左移一位变为F2300H

物理地址= 基础地址 + 偏移地址 #F2300H + C8H = F23C8H,即物理地址为F23C8H,刚好为20bit

这里注意,一个物理地址可能对应多个 段地址和偏移地址的组合,例如:

21F60H = 2000H * 10H +1F60H

21F60H= 2100H * 10H +0F60H

21F60H= 21F6H * 10H +0000H

21F60H= 1F00H * 10H + 2F60H

也就是说,内存地址是通过物理地址来表示的,只要段地址和偏移地址的组合生成的物理地址正确,就可以取到正确的数据。

5.查看某块地址的内存

使用-d查看2000:1F60地址开始的内存数据:

2e5153aa016240817e96227ea41c7c6f.png

使用-u查看2000:1F60地址开始的内存数据,但是解析成指令:

90247918549be304c1f6c0b4bc476600.png

虽然我们可以将内存的数据显示成普通数据和指令,但对于CPU,他只会将内存中某个特殊区域的数据当成指令。下节我们对其进行探究。

6.指令存储位置

当我们使用debug -r查看寄存器时:

40dfa090f2293b39a27a17d95753953e.png

可以看到 MOV AL,FC 指令对应的内存地址为073F:0100。

通过观察,我们可以确定IP寄存器保存着该指令的偏移地址。

而DS、ES、SS、CS这四个寄存器中,谁保存了指令的段地址,目前无法确定。

我们可以通过修改这四个寄存器的值,来看指令是否发生变化,从而确定是哪个寄存器保存指令的段地址:

5ea6febcaa95c8ce223cc466419fa50c.png

cc2dd70557338d174fc7d849451ec73d.png

c4ec5c26927ca1c3fe9bd4c8674787b7.png

从上面的过程可以看出,当我们修改CS寄存器的值时,指令发生了改变,说明CPU将CS寄存器中存储的数据作为指令的段地址。

总结:在8086 CPU中,CPU将CS:IP地址所保存的内容,全部当做指令来执行。

7.将内存中的数据作为指令运行

首先,我们使用debug -e 2000:0000向指定内存中存入一些数据:

e68014b0e38a24d076848b360f2fd5d3.png

然后使用debug -u查看一下翻译成指令是什么样子:

3541516ac0eb1d3c117f33fba6e56e8f.png

查看一下当前CS:IP在什么位置:

fa3772c1d3cec0e8aa5f861ce8965544.png

可以看到,当前CS:IP地址为073F:0100。我们将其修改为2000:0000:

c8503f5f25d21570fc33187159b8bb05.png

可以看到,下面的指令变为我们存入内存数据对应的指令。

此时就可以用 debug -t 来执行了:

6f2aa9d5f00e57bccb6ed6aba2a10496.png

总结:从这一节我们可以看出,数据在内存中是没有区别的,只有当CS:IP指向的内存中的数据,才会被CPU当做指令来执行。

8.寄存器种类

在前面我们已经看到了有很多种寄存器,AX~DX为通用寄存器,用于存储数据(当然也可能有特殊用途,例如BX和CX就可以用来当作偏移地址寄存器使用,而AX和DX一般用于处理数据)。

而DS、ES、SS、CS用于存储段地址,IP用于存储指令偏移地址。

除了以上这些,剩下的SP、BP、SI、DI也是用于存储偏移地址的,我们在后面的章节会对其进行了解。

这些寄存器可能都有特殊的用途,不能对其一概而论。

==

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值