8086汇编语言(02)
本文最后更新于248 天前,其中的信息可能已经过时,如有错误可以直接在文章下留言

1.CPU概述

中央处理器(CPU,Central Processing Unit)是一块超大规模的集成电路,是一台计算机的运算核心和控制核心。它的功能主要是解释计算机指令以及处理计算机软件中的数据。一个典型的CPU由运算器、控制器、寄存器等器件组成,这些器件靠内部总线相连。

内部总线实现的是CPU内部各个器件之间的联系,而外部的三种总线实现CPU和主板上其他器件的联系。

2.16位结构的CPU

16位结构描述一个CPU具有以下几个方面特征。

1.运算器一次最多可以处理16位的数据

2.寄存器的最大宽度为16位

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

3.寄存器

8086 CPU 中寄存器总共为 14 个,且均为 16 位,可以存放两个字节。即 AX,BX,CX,DX,SP,BP,SI,DI,IP,FLAG,CS,DS,SS,ES 共 14 个。而这 14 个寄存器按照一定方式又分为了通用寄存器,控制寄存器和段寄存器。

不同计算机的寄存器总类可能有所不同,但是差别不大,且通用寄存器不会有太大改变。

4.通用寄存器

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

下图以AX为例,我们看一下其逻辑结构

从0开始,计算机就是喜欢从0开始嘛。像在逆向中看到的大多是EAX、EBX、ECX等,这些都是32位的寄存器,毕竟我们现在的电脑肯定高级多了,寄存器也不止16位了。

再来看16位数据在寄存器中的存放情况,如图,以20000为例

数据在计算机中以二进制方式存储,不多说,这里16位数据能存储的最大值也就是2的16次方减一,这个也没啥好说的,计算机专业的估计都明白。

而8086上一代CPU中的寄存器都是8位的,为保证兼容性,这四个寄存器都可以分为两个独立的8位寄存器使用,一个16位的寄存器就可以分为高位和地位。

AX可以分为AH和AL,BX可以分为BH和BL,CX和DX同理 。(H指High,L指Low)

当分为两个8位寄存器来使用的时候,高位全部填0,当作不存在。低位存储数据。

以AX为例,低8位(0位~7位)构成了AL寄存器,高8位(8位~15位)构成了AH寄存器。AH和AL都是可以独立使用的8位寄存器。我们存一个数据在AX寄存器中,拆开成两个8位寄存器跟一个16位寄存器的来看的话就是不同的数据,如图。

5.字

在8086汇编语言的学习中,一个字等于两个字节,等于16个比特,它刚好可以存在一个16位的寄存器当中,这个字的高位字节和低位字节自然就存在了这个寄存器的高8位寄存器和低8位寄存器当中。

但是看了视频弹幕发现,字的定义好像(我可不确定)是指cpu一次处理二进制代码的位数,它不是固定的,它的长度与计算架构有关,比如32位计算机,一个字就是32位,换算成字节就是4字节;同样的64位计算机,一个字就是64位,也就是8字节。字也是计算机一次处理数据的最大单位。

所以这里8086CPU的一个寄存器一次处理二进制代码的位数是16,所以一个字才等于2个字节。

6.简单汇编指令

首先,汇编指令并不区分大小写。

计算机的语言习惯从后面往前面赋值,所以上面的汇编语言比如第一行,是让逗号后面的值赋给前面的寄存器,这个mov和add的作用上图已经解释的很清楚了,这里有个陌生的是寄存器中的值也是可以转移给另外一个寄存器的。

其实我们把bx看作一个变量,ax也看作一个变量,计算机高级语言不也可以将一个变量的值赋给另外一个变量。

这里提一下上面说的一个通用寄存器分为两个八位寄存器来用如何在汇编语言里面体现,代码如下

mov ax,001AH
mov bx,0026H
add ah,bl

先说一下数据后面的H,表示这个数据是16进制(Hex)的数据,在运行了上面的汇编指令之后,寄存器AX中的数据是多少呢?

答案是261AH把,我们把16位寄存器分为两个8位寄存器后,ah中的数据为00,al中的数据为1A,bh中的数据为00,bl中的数据为26,那ah在执行第三行的汇编指令之后,就变成了26,那么ax寄存器中存储的数也就是261AH。

7.8086CPU给出物理地址的方法

8086有20位地址总线,可传送20位地址,,寻址能力即为1M。

但8086内部为16位结构,它只能传送16位的地址,表现出的寻址能力却只有64K。

那么就有问题,8086CPU如何用内部16位的数据转换成20位的地址呢?

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

如图为8086CPU相关部件的逻辑结构,8086CPU读写内存的时候,会发生以下程序。

1.CPU的相关部件提供两个16位的地址,一个称为段地址,一个称为偏移地址。

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

3.地址加法器将两个16位地址合并成一个20位的地址。

而地址加法器合成物理地址的方法是;

物理地址 = 段地址 × 16 + 偏移地址

一个16进制的数据乘16其实就是向左左移一位,比如十进制的10,乘10之后不就是100,向左移动了一位。

如图就是其工作原理的举例,但是其实有一个问题,就是比如说一个物理地址123C8,它其实可以由,1230的段地址和00C8的偏移地址合成得到,它也可以由1200的段地址和03C8的偏移地址得到。即同一个物理地址,却由不同的段地址和偏移地址合成得到了,那么寻址就出现了问题把,这个问题我们后面再探讨。

用两个比喻来理解。第一个比喻

第二个比喻呢就更贴切,就是我们只能通过纸条来通信,一个人问我图书馆的地址,我只能将它写在纸上告诉他,显然我必须有一张可以容纳4位数据的纸条才能写下2826这个数据,可惜我没有,只有两张可以容纳三位数据的纸条,那么我就可以在第一张纸条上写下200,在第二张纸条上写下826,然后告诉问路人,你只用将第一张纸条的数据乘10再加上第二张的数据就是图书馆的地址了。段地址加偏移地址的方法就是这样,有因为8086自己的不足,运用了这种方法来给出物理地址。

8.段

刚刚我们提到了段地址,有的人就会有错误认识,即内存被划分为一个一个的段,每一个段有一个段地址。

这样的说法是错误的,内存并没有分段,段的划分来自于CPU,是由于8086CPU用“(段地址×16)+偏移地址=物理地址”的方式给出内存单元的物理地址,使得我们可以用分段的方式来管理CPU。

所以可以说,段其实是8086CPU用于对内存管理的一种方法,内存表示一脸懵逼,完全不知道CPU是怎么得到它的地址,也不必要知道CPU是如何得到,内存所要关心的是我要给CPU什么,从CPU那得到什么,至于你CPU是通过GPS导航到我家的还是通过其它什么方法知道我家的,一概与我无关。而CPU得到他地址的方式就是自己划分段来更好的管理。

以后,在编程时可以根据需要,将若干地址连续的内存单元看作一个段,,用段地址×16定位段的起始位置(基础地址),用偏移地址定位段中的内存单元。

有两个点需要注意,一是段地址×16必然是16的倍数,所以一个段的起始地址也一定是16的倍数。二是偏移地址为16位,16位地址的寻址能力为64KB,所以一个段的长度最大为64KB,不然用偏移地址就定位不到内存单元了。

例如,给定段地址为1000H,用偏移地址寻址,CPU的寻址范围为10000H到1FFFFH。

对于8086PC机,数据在21F60H内存单元中,可以用两种方式来描述:

1.数据存在内存2000:1F60单元中,这种方式也是我们后面汇编学习经常用到的。

2.数据存在内存的2000段中的1F60H单元中。

可根据需要,将地址连续,起始地址为16的倍数的一组内存单元定义为一个段。

9.段寄存器

段寄存器就是提供段地址的。8086CPU有4个段寄存器,分别是CS(Code Segment)、DS(Data Segment)、SS(Stack Segment)、ES(Extra Segment)

本篇主要学习CS寄存器。

10.CS和IP

CS和IP是8086CPU里面最关键的寄存器,它们指示了CPU当前要读取指令的地址。这个知识点也很重要

CS为代码段寄存器,IP为指令指针寄存器。

当CPU开始工作时,首先CS中的段地址和IP中的偏移地址进入地址加法器,合成20000的物理地址,通过输入输出控制电路,再通过20位地址总线,索引到内存的20000的位置,这个地址包含了三个字节,这里提一下,我们看的这里内存空间,数据高位地址存储在高地址,低位地址存储在低地址,所以存储了0123B8这个数据,这里的B8应该时汇编指令的机器码吧,0123就是数据,0123B8进入了指令缓冲器,再执行,AX的值就被0123H覆盖了,刚执行的汇编指令在内存空间中包含了三个字节,IP就要自增3得到0003,然后再合成出物理地址20003,然后继续执行汇编指令。

总结一下工作过程就是从CS:IP指向内存单元读取指令,读取得指令进入指令缓冲器,该条指令被执行完成后,IP中得值要加上所读取指令得长度,从而指向下一条指令,然后重复该步骤,一直往下读。

在CPU加电启动后(即CPU刚开始工作时),CS和IP被设置为CS=FFFFH,IP=0000H。即8086CPU计算机刚启动时,CPU从FFFF0H单元中读取指令执行

在任何时候,CPU将CS和IP得内容当作指令得段地址和偏移地址,用它们合成指令的物理地址,到内存中读取指令码,执行。如果说,内存中的一段信息曾被CPU执行过的话,那么,它所在的内存单元必然被CS:IP指向过。

在CPU中,程序员能够用指令读写的部件只有寄存器,程序员可以通过改变寄存器中的内容实现对CPU的控制。CPU从何处执行指令是由CS,IP中的内容决定的,程序员可以通过改变CS,IP中的内容来控制CPU执行目标指令

我们知道,mov ax,123 可以改变寄存器AX中的值为123,mov指令可以改变8086CPU大部分寄存器的值,被称为传送指令。但是很遗憾,mov指令不可以用于设置CS,IP的值,但是我们可以用转移指令来修改CS,IP里面的内容。

jmp 段地址:偏移地址
jmp 2AE3:3   
jmp 3:0B16

上面的汇编指令第一条就是指跳转到段地址为2AE3,偏移地址为3的地址处,这时候CS中的值会被改为2AE3,IP中的值会被改为3物理地址也就是2AE33H。

那第二条指令给出的物理地址是30B16吗?当然不是,这里的段地址为3,乘16后得到0030,再加上偏移地址得到物理地址0B46H。

上面的方法是同时修改CS和IP中的值,那么如何仅仅修改IP中的内容呢

mov ax,200H
jmp ax #jmp 某一合法寄存器

用以上汇编指令就可以用寄存器中的值修改IP中的值,而其功能实际上也是跳转,假设CS的值为2000,其功能等同于jmp 2000:200。

做一道题

初始的CS:IP指向了指令mov ax,6622H,执行了这条指令后寄存器ax中的值为6622H,然后IP自增3,因为这个指令占了三个字节,然后执行指令jmp 1000:3,然后跳转到左边那列指令mov ax,0000处,然后寄存器ax中的值就变为0,IP自增3,执行指令mov bx,ax,寄存器bx中的值变为0,然后IP自增2,执行指令jmp bx,此时IP的值变为寄存器bx中的值0,并跳转到指令mov ax,0123H处,执行后IP自增3执行指令mov ax,0000,然后就陷入一个死循环。

11.代码段

可以将长度为n(n<=64kb)的一组代码,存在一组地址连续、起始地址为16的倍数的内存单元中,这段内存用来存放代码,从而定义了一个代码段。

mov ax,0000 (B8 00 00)
add ax,0123 (05 23 01)
mov bx,ax   (8B D8)
jmp bx      (FF F3)

上面这段长度为10个字节的指令,存在从123B0H到123B9H的一组内存单元中,我们就可以认为,这段内存单元是用来存放代码的,是一个代码段。段地址为123BH,长度为10字节。

那如何使得代码段中的代码被执行呢?

将一段内存当作代码段,仅仅是我们在编程时的一种安排,CPU并不会因为这种安排,就自动地将我们定义得代码段中的指令当作指令来执行。CPU只认CS:IP指向的内存单元中的内容为指令。所以要将CS:IP指向所定义的代码段中的第一条指令的首地址。

文末附加内容

评论

  1. Nevaeh1847
    Windows Chrome
    8 月前
    2024-2-23 15:46:47

    Modern Talking был немецким дуэтом, сформированным в 1984 году. Он стал одним из самых ярких представителей евродиско и популярен благодаря своему неповторимому звучанию. Лучшие песни включают “You’re My Heart, You’re My Soul”, “Brother Louie”, “Cheri, Cheri Lady” и “Geronimo’s Cadillac”. Их музыка оставила неизгладимый след в истории поп-музыки, захватывая слушателей своими заразительными мелодиями и запоминающимися текстами. Modern Talking продолжает быть популярным и в наши дни, оставаясь одним из символов эпохи диско. Музыка 2024 года слушать онлайн и скачать бесплатно mp3.

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇