x86汇编语言(2) 认识8086处理器

x86汇编语言(2) 认识8086处理器

8086的通用寄存器

结构如图:由8个通用寄存器组成,每个寄存器之间都可以传送数据,其中AX,BX,CX,DH都可以分成高8位和低8位的寄存器

image-20210319152838114

每个寄存器都是16位。

AX、BX、CX、DH可以分为高字节、低字节;16位处理器中1个字16位,2个字节

image-20210319153603837

我们改变其中一个寄存器的值,不影响另一个,如改变了AH的值,AL的值不变,但AX的值改变

image-20210319153749336

8086的内存访问和字节序

16位寄存器中的内容被写入8位内存中,可以分成两个8位传送进去。如图,高字节被写入内存的高地址单元,低字节被写入内存的低地址单元,我们称为低端字节序。

image-20210319154252659

AH等8位寄存器也可传送到内存中,只需要一半的地址线(传送出也一样)

image-20210319154547407

程序的分段

内存中的程序分为代码段和数据段,代码段保存要执行的指令,指令中会有执行过程所需数据的地址,执行时通过再次访问程序的数据段,再进行相应的操作

image-20210319155726969

如下图,第一条指令通过访问0C00处的一个字(053C)传送到AX寄存器,第二条指令访问0C02的一个字(0F8B),再与寄存器AX的内容相加,最后存入0C02中。

image-20210319155624740

详细的分段:

1、代码段/只读段:二进制指令、字符串字面值,具有const属性且被初始化过的全局、静态变量。
2、数据段:被初始化过的全局变量和静态变量。
3、bss段:未被初始化过的全局变量和静态变量,进程一旦加载成功,就会把这段内存清理为零。
4、堆:动态的分配、管理,需要程序员手动操作。有低地址向高地址拓展
5、栈:非静态的局部变量,包括函数的参数、返回值。由高地址向低地址拓展
从高地址向低地址使用,和堆内存之间存在一段空隙.
堆区和栈区中间存在一块间隙,一方面是为堆和栈增长预留空间,另一方面存放共享库、共享内存。

程序的重定位难题

如图,使用一个IPR来保存即将执行的指令的地址,当执行完这条指令时,计算出下一条指令的地址并更新。

image-20210319161814069

但是内存中存入指令的地址是不确定的,所以数据段地址的定位会不准确。如下图,指令偏移到了1000,根据地址取数据段的值也不再准确,比如根据指令会访问到0C00地址的内容。出现这种情况的原因是我们使用了物理地址,这是绝对地址。

image-20210319162141780

段地址和偏移地址

如图,我们可以看到,1C00距离数据段起始地址的偏移量为0,1C02距离段起始地址的偏移量为2

image-20210319162835104

因此,数据段的每个数都有两个地址,一个是物理地址,一个是相对段起始位置的偏移量,称为偏移地址。这样代码段的地址就可以改为偏移地址了。每一个段的起始地址称为段地址

image-20210319163316657

使用这种方式,处理器的变化:DSR用来保存数据段的起始地址,根据这个地址加上偏移地址可以找到数据段的物理地址。IPR用来保存代码段指令的地址

image-20210319163454313

8086内存访问的困境

如图,Intel 8086处理器有16根数据线,用来传送数据,有20根地址线,用来访问内存中的地址,20根地址线可以访问的内存为2的20次方即1MB。

image-20210319164221141

如图,CS用来保存代码段要执行指令的地址,DS用来保存数据段的起始地址。

image-20210319164547109

而这些寄存器都是16位的,容纳不了20位的地址。这该如何解决?

8086选择段地址的策略

8086处理器选择以0结尾的地址作为段地址,这样通过右移4位(十六进制数33CE0变成了33CE),这样就可以存入寄存器中。

image-20210319165654544

但CS寄存器保存的是要执行的指令的地址,如30CE3,后面的3是不能丢掉的,这又要怎么解决呢?

8086的内存访问过程

为了解决上面的问题,我们引入了IP寄存器来保存数据段的偏移地址。这样,内存访问的过程就完整了:

  1. 程序开始执行
  2. 将代码段的段地址右移四位,保存到CS寄存器
  3. 将数据段的段地址右移四位,保存到DS寄存器
  4. 把第一条指令的偏移量0000保存到IP寄存器
  5. 取出CS寄存器中的数据,左移4位,加上IP寄存器的数据,结果输入到20位地址线,内存根据地址线的地址取访问代码段的指令
  6. 根据代码段指令中数据段的偏移地址,取出DS寄存器的数据左移四位并相加,得到物理地址,根据这个物理地址取访问数据段的数据,并执行操作码相应的操作
  7. 指令执行结束后,计算出下一条指令的偏移地址(根据原偏移地址加上原指令的长度相加),更新IP寄存器偏移地址的值
  8. 继续执行指令,指定遇到终止的指令。

image-20210319170722037

逻辑地址和分段地址的灵活性

如图,以65C70作为段地址,我们可以用65C7:0000来表示物理地址位65C70的内存单元,用65C7:0005来表示物理地址位65C75的内存单元。这个地址称为逻辑地址

image-20210319172506588

则22567的逻辑地址可能为:2256:0007,也可能是2255:0017,这取决于它的段地址在哪里,其中偏移地址最大为FFFF。

image-20210319173044999

习题

image-20210319173407060

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值