|
查看: 2541|回复: 21
|
汇编自学教材--《汇编语言》王爽著~!读后笔记
[复制链接]
|
|
|

楼主 |
发表于 5-3-2009 04:29 PM
|
显示全部楼层
|
|
|
|
|
|
|
|
|
|

楼主 |
发表于 5-3-2009 05:26 PM
|
显示全部楼层
1.2 汇编语言的产生
早期的程序员们,很快就发现使用机器语言带来的麻烦,它是如此难于辨别和记忆,于是汇编语言产生了!
汇编语言的的主体是汇编指令。汇编指令和机器指令的差别在于指令的表达方法上。汇编指令是机器指令便于记忆的书写格式!
例如:机器指令 1000100111011000 表示把寄存器 BX 的内容送到AX 中。
使用汇编指令则是写成 mov ax,bx
(所谓的寄存器(Register),是CPU 里面,可以储存数据的零件,一个CPU 中有多个寄存器。AX 是其中一个寄存器的代号,BX 是另一个寄存器的代号,更详细的内容以后的课程中会提到)
此后,程序员们就用汇编指令编写源程序。
可是,计算机的硬件(cpu)能读懂的是机器指令,那么如何让计算机执行程序员用汇编指令编写的程序呢?
这时,就需要一个能够把汇编指令 转换 成机器指令的翻译程序!
(简单来讲就是 把汇编指令 convert 成 二进制 的机器指令,)
这种翻译程序被称为 编译器
程序员用汇编语言写出源程序,再用汇编 编译器 将指令编译成机器码,由计算机最终执行。
图1.1 描述了这个工作过程!

|
|
|
|
|
|
|
|
|
|
|

楼主 |
发表于 5-3-2009 05:53 PM
|
显示全部楼层
|
|
|
|
|
|
|
|
|
|

楼主 |
发表于 5-3-2009 06:55 PM
|
显示全部楼层
|
|
|
|
|
|
|
|
|
|

楼主 |
发表于 6-3-2009 06:19 PM
|
显示全部楼层
1.5 指令和数据
指令和数据是应用上的概念。 在内存或磁盘上,指令和数据没有任何区别,都是二进制信息。CPU 在工作的时候,把有的信息看作指令,有的信息看作数据,为同样的信息赋予不同的意义。就像围棋的棋子,在棋盒里的时候没有任何区别,但在棋盘上对弈的时候就有了不同的意义!例如:内存中的二进制信息 1000100111011000 ,计算机可以把它看作大小为 89D8 H 的数据来处理,也可以将其看作指令 mov ax,bx 来执行。
1000100111011000 -----> 89D8 H (数据)
1000100111011000 -----> mov ax,bx ( 程序)
(来到这里有一点必须提一提,这一节中提到的 "89D8 H " 其实是一个 十六进制的值来的!十六进制 89D8 转换成二进制为 1000100111011000 B ,而那个 H ,正是代表 十六进制 Hexadecimal (Hex ) 的符号! 这本教材以后都会用这种方式来表达 十六进制 的值) |
|
|
|
|
|
|
|
|
|
|

楼主 |
发表于 10-3-2009 08:17 PM
|
显示全部楼层
1.6 存储单元
存储器被划分成若干个存储单元,每个存储单元从 0 开始顺序编号,例如一个存储器有128 个单元,编号从
0 ~ 127。
如 图1.2 所示!

那么,一个存储单元能存储多少信息呢?
电子计算机的最小单位是 bit (音译为比特),也就是一个二进制位。
8 个 bit 组成一个 Byte ,一个 Byte 我们通常称之为一个 字节 。
微型机存储器的存储单元可以存储一个字节,即8 个 二进制位(bit) 。
一个存储器有 128 个存储单元,它可以存储 128 个字节。 (128* 8 = 1024 个 bit)
微机存储器的容量是以字节为最小单位来计算的。 对于拥有 128 个存储单元的存储器,我们可以说,它的容量是 128 字节。
对于大容量的存储器一般还用以下单位来计量容量(以下用 B 来代表 Byte )
1 KB = 1024 B
1 MB = 1024 KB
1 GB = 1024 MB
1 TB = 1024 GB
磁盘的容量单位同内存的一样,实际上以上的单位是微机中常用的计量单位。 |
|
|
|
|
|
|
|
|
|
|

楼主 |
发表于 10-3-2009 11:26 PM
|
显示全部楼层
1.7 CPU 对存储器的读写
1.6 节提到,存储器被划分成多个存储单元,存储单元从零开始顺序编号。
这些编号可以看作存储单元中的地址。
就像一条街,每个房子都有门牌号码。
CPU 要从内存中读取数据,首先要指定存储单元的地址。
也就是说,CPU 要先确定读取哪一个存储单元中的数据。 就像在在一条街找人,先要确定他住哪个房子里。
另外,在一台微机中,不只有存储器这一种器件。 CPU 在读写数据时还要指明,它要对哪一种器件进行操作,进行哪种操作; 是从中读出数据, 还是向里面写入数据。
可见,CPU 要想进行数据的读写,必须和外部器件(标准的说法是其他的电子芯片)进行 3 类信息交互:
--存储单元的地址 (地址信息)
--器件的选择,读或写的命令 (控制信息)
--读或谢的数据 (数据信息)
那么 CPU 是通过什么将地址,数据和控制信息传到存储芯片中的呢? 电子计算机能处理,传输的信息都是电信号,电信号当然要用导线传送。 在计算机中专门有连接CPU 和其他芯片的导线,通常称为总线。
总线物理上来讲,就是一根根导线的集合。 根据传送信息的不同,总线从逻辑上又分为3类, 即
地址总线,控制总线和数据总线。
CPU 从 3 号单元中读取数据的过程(见图 1.3) 如下:

(1)CPU 通过地址线将地址信息 3 发出。
(2)CPU 通过控制线发出内存读命令,选中存储器芯片,并通知它,将要从中读取数据。
(3)存储器将 3 号单元中的数据 08 通过数据线送入 CPU。
写操作与读操作的步骤相似。 向 3 号单元写入数据 26 :
(1)CPU 通过地址线将地址信息 3 发出
(2)CPU 通过控制线发出内存写命令,选中存储器芯片,并通知它,要向其写入数据。
(3) CPU 通过数据线将数据 26 送入内存的3号单元中。
从上面我们知道 CPU 是如何进行数据读写的,可是,我们如何命令计算机进行数据的读写呢?
要让一个计算机或微处理器工作,应向它输入能够驱动它进行工作的电平信息(机器码)。
对于 8086 CPU,下面的机器码能够完成从 3 号单元读数据:
机器码:101000000000001100000000
含义:从3号单元读取数据送入寄存器 AX
CPU 接收这条机器码后将完成上面所述的读写工作。
机器码难于记忆,用汇编指令来表示,情况如下:
机器码:101000000000001100000000
对应的汇编指令:MOV AX,[3]
含义:传送3号单元的内容到 AX
[ 本帖最后由 旭阳 于 12-3-2009 10:30 PM 编辑 ] |
|
|
|
|
|
|
|
|
|
|

楼主 |
发表于 12-3-2009 11:15 PM
|
显示全部楼层
1.8 地址总线
CPU 是通过地址总线来指定存储器单元的。 地址线上能传送多少个不同的信息,CPU 就可以对多少个存储单元进行寻址。
现假设,一个 CPU 有 10 根地址线,让我们来看一下它的寻址情况。
在电子计算机中,一个导线可以传送的稳定状态只有两种,高电平或是低电平,用二进制表示就是 1 或 0
10根导线可以传送10 位 二进制数据。 而10 位二进制数可以表示多少个不同的数据呢?
2的10 次方个,最小数为0 最大数为 1023。
图1.4 展示了一个具有10根地址线的 CPU 向内存发出的地址信息 11 时
10根 地址线上传送的二进制信息。考虑一下,访问地址为 12, 13,14 等的内存单元时,地址总线上传送的内容是什么?
图1.4
一个 CPU 有N 根地址线,则可以说这个 CPU 的地址总线的宽度为 N 。
这样的CPU 最多可以寻找 2 的 N次方个内存单元。
(10 根导线,可以传送信息的变化范围从 0000000000 ~ 1111111111 ,这是个二进制,我们可以把它转换成 10 进制,就可以看到其变化范围由 0 ~ 1023)
[ 本帖最后由 旭阳 于 13-3-2009 08:16 AM 编辑 ] |
|
|
|
|
|
|
|
|
|
|
发表于 18-3-2009 04:19 PM
|
显示全部楼层
|
|
|
|
|
|
|
|
|
|

楼主 |
发表于 24-3-2009 10:30 AM
|
显示全部楼层
1.9 数据总线
CPU 与内存或其他器件之间的数据传送是通过数据总线来进行的。 数据总线的宽度,决定了CPU 和外界的数据传送速度。
8 根数据总线一次可以传送一个8位二进制数据(即一个字节)。
16根数据总线一次可以传送2个字节。
8088 CPU 的数据总线宽度为 8, 8086 CPU 的数据总线宽度为 16 。我们来分别看一下它们向内存中写入数据 89D8 H 时,是如何通过数据总线传送数据的。
图1.5 展示了8088 CPU 数据总线上的数据传送情况;
图1.6 展示了8086 CPU 数据总线上的数据传送情况。

8086 cpu 有16根数据线,可一次传送 16 位 数据,所以可以一次传送数据 89D8 H ;
而 8088 cpu 只有8 根数据线,一次只能传 8 位数据,所以向内存写入数据 89D8 H 时
需要进行两次数据传送。
(在 1.6 节 中我们知道,电子计算机最小的单位是 bit (一个二进制位),等于一个电平(可以是高电平或低电平),而以我的理解是,8个 bit 组成 一个Byte (字节)如果说要一次要传送一个字节,最低要求就必须要8 根导线,
但是如果一次要传送2个字节,只有8根数据导线的话,只好分成两次来传送了,总结是,一切都是由数据导线的数量来决定数据的传送速度)
[ 本帖最后由 旭阳 于 24-3-2009 10:58 AM 编辑 ] |
|
|
|
|
|
|
|
|
|
|

楼主 |
发表于 24-3-2009 11:37 AM
|
显示全部楼层
1.10 控制总线
CPU 对外部器件的控制是通过控制总线来进行的。在这里控制总线是个总称,控制总线是一些不同控制线的集合。
有多少根控制总线,就意味这 CPU 提供了对外部器件的多少种控制。
所以,控制总线的宽度决定了 CPU 对外部器件的控制能力。
前面所讲的内存读,或写命令是由几根控制线综合发出的。
其中有一根名为“读信号输出控制线” 负责由 CPU 向外传送读信号,CPU 向该控制线上输出低电平表示将要读取数据:
有一根名为“写信号输出控制线” 则负责传送写信号。 |
|
|
|
|
|
|
|
|
|
|

楼主 |
发表于 24-3-2009 12:26 PM
|
显示全部楼层
|
|
|
|
|
|
|
|
|
|

楼主 |
发表于 24-3-2009 07:54 PM
|
显示全部楼层
1.11 内存地址空间 (概述)
什么是内存地址空间呢? 举例来说,一个 CPU 的地址线宽度为 10 ,那么可以寻址 1024 个内存单元,而这 1024 个可寻到的内存单元就构成这个 CPU 的内存地址空间。下面进行深入讨论。 首先要介绍两个部件基本知识----主板和接口卡。
1.12 主板
在每一台 PC 机中,都有一个主板,主板上有核心器件和一些主要器件,这些器件通过总线(地址总线,数据总线,控制总线)相连。这些器件有 CPU, 存储器,外围芯片组,扩展插槽等等。扩展插槽一般上插有 RAM 内存条和各类接口卡。
1.13 接口卡
计算机系统中,所有可用程序控制其工作的设备,必须受到 CPU 的控制。CPU 对外部设备都不能直接控制,如显示器(LCD ,monitor) 音箱,打印机等。直接控制这些设备进行工作的是插在扩展插槽上的接口卡。 扩展插槽通过总线和 CPU 相连所以接口卡也通过总线同CPU 相连。 CPU 可以直接控制这些接口卡,从而实现 CPU 对外部设备的间接控制。 简单来说,就是CPU 通过总线向接口卡发送命令,接口卡根据 CPU 的命令控制外部设备进行工作。
新一代的电脑主板,往往都内置(build in )了显示器接口,音效接口,甚至还出现了 USB 接头--这种简单方便的设备, 不像早期的电脑,显示器的接口有个独立的接口卡,音箱的接口也有个独立的接口卡等。
当我们觉得主板上内置的显示卡性能不能满足我们的要求(例如玩一些画面高解析度的游戏,3D 画面的游戏等),内置显示卡只有128 MB 的内存,玩的时候会觉得画面卡着卡着的,不顺畅,要想提升显示卡的性能,就可以购买一个512MB 内存或以上的独立显示接口卡,插在主板上的扩展槽。

我们也可以把电脑比作人体。
要完成削苹果这个动作,大脑(CPU )通过 人体的神经线(控制总线),向双手(扩展插槽)发出
“削苹果“这个指令,于是双手(扩展插槽)举起了刀子和苹果(接口卡)完成 “削苹果“这个动作!
[ 本帖最后由 旭阳 于 24-3-2009 09:21 PM 编辑 ] |
|
|
|
|
|
|
|
|
|
|

楼主 |
发表于 25-3-2009 07:48 PM
|
显示全部楼层
1.14 各类存储器芯片
一台 PC 机中,装有多个存储器芯片,这些存储器芯片从物理连接上看是独立的,不同的器件。
从读写属性上看分为两类: -----(1) 随机存储器( RAM)
(2)只读存储器( ROM)。(在 5# 有粗略的图片介绍)
随机存储器可读可写,但必须带电存储,关机后失却电源,存储的内容就会丢失;
只读存储器只能读不能写入,关机后其中的内容不会丢失。
看看下图

这是电板的上的BIOS,一般上我们通过 BIOS 来调试电板上各种器件如电源,CD-ROM ,Hard Dick 等等设备的参数 ,它不存储在 hard dick 里,就存储在这一节所介绍的 只读存储器 (ROM) 里.
这些存储器从功能和连接上又可分为以下几类:
*** 随机存储器
用于存放供CPU 使用的绝大部分程序和数据,主随机存储器一般由两个位置上的RAM 组成,
装在主板上的 RAM 和插在扩展插槽上的 RAM 。
*** 装有BIOS (Basic Input /Output System, 基本输入输出系统 的缩写)的 ROM
BIOS 是由主板和各类接口卡 ( 如:显示卡,网卡等) 厂商提供的软件系统,可以通过它利用
硬件设备进行最基本的输入输出.
在主板和某些接口卡上插有存储相应 BIOS 的 ROM .
例如:主板上的 ROM 存储着主板的 BIOS (通常称之为 系统 BIOS )
显示卡上的 ROM 中存储着显示卡的 BIOS ; 如果网卡上装有ROM ,那其中就可以存储网卡的 BIOS .
*** 接口卡上的 RAM
某些接口卡需要对大批量的输入,输出 数据进行暂时存储,在其装有 RAM . 最典型的是显示卡上
的 RAM ,一般称为显存. 显示卡随时将显存中的数据向显示器上输出. 换句话说,我们将需要显示
的内容写入显存,就会出现在显示器上.

[ 本帖最后由 旭阳 于 25-3-2009 09:21 PM 编辑 ] |
|
|
|
|
|
|
|
|
|
|

楼主 |
发表于 25-3-2009 09:33 PM
|
显示全部楼层
1.15 内存地址空间
上述那些存储器,它们在物理上是独立的器件,但是它们有两个共同点:
** 都和CPU 的总线相连.
** CPU 对它们进行读 或写 的时候都通过控制线发出内存读写命令.
也就是说,CPU 在操纵 和控制它们的时候,把它们都当作内存来对待, 把它们总的看作一个由若干存储单元组成的逻辑存储器. 这个逻辑存储器就是我们所说的内存地址空间. 在汇编这门课中,我们所面对的是内存地址空间.

在图 1.8中,所有的物理存储器被看作一个由若干存储单元组成的逻辑存储器,每个物理存储器在这个逻辑存储器中占有一个地址段,即一段地址空间。
CPU 在这段地址空间中读写数据,实际上就是在相对应的物理存储器中读写数据。
假设,图1.8中的内存地址空间段分配如下:
地址 0~7FFF H 的 32 KB 空间为主随机存储器的地址空间;
地址 8000 H~9FFF H 的8 KB 空间为显存地址空间;
地址 A000 H~FFFF H 的 24 KB 空间为各个 ROM 的地址空间。
这样 CPU 向内存地址为 1000 H 的内存单元中写入数据,这个数据就被写入主随机存储器中;
CPU 向内存地址为 8000 H 的内存单元中写入数据,这个数据就被写入显存中,然后会被显卡输出到显示器上;
CPU 向内存地址为 C000 H 的内存单元中写入数据的操作是没有结果的,C000 H 单元中的内容不会被改变,C000 H 单元实际上就是 ROM 存储器中的一个单元(ROM 存储器 是只读存储器,只能读,不能写)
内存地址空间的大小受 CPU 地址总线宽度的限制。 8086 CPU 的地址总线宽度为20,可以传送2^20 个不同信息的地址空间(大小从0 至 2^20 - 1) .即可以定位 2^20 个内存单元,则 8086 CPU 的内存地址空间大小为 1 MB .同理,80386 CPU 的地址总线宽度为 32,则内存地址空间最大为 4GB.
(2的20次方~得到的数为1048576 B ,转换成 KB 则除以 1024 ,得到的值为 1024KB ;1MB = 1024 KB
80386 CPU 的地址总线的宽度为32 --2的 32 次方 得到的值为 4294967296 B 除以 1024 =4194304 KB ,
再除以1024= 4096 MB,1 GB =1024 MB ,4096 MB 除以 1024 = 4 GB~)
我们在基于一个计算机硬件系统编程的时候,必须知道这个系统中的内存地址空间分配情况.
因为当读者想在某类存储器中读写数据的时候,读者必须知道它的第一个单元的地址和最后一个单元的地址,才能保证读写操作是在预期的存储器中进行.
比如,读者希望向显示器输出一段信息,那么读者必须将这段信息写到显存中,显卡才能将它输出到显示器上。 要向显存中写入数据,读者必须知道显存的内存地址。
不同的计算机系统的内存地址空间的分配情况是不同的,图1.9展示了 8086 PC 机内存地址空间分配的基本情况。

图1.9 告诉我们,我们从地址0~9FFFF 的内存单元中读取数据,实际上就是在读取主随机存储器中的数据; 向地址 A0000~BFFFF 的内存单元中写数据,就是向显存中写入数据,这些数据会被显示卡输出到显示器上; 我们向地址 C0000~FFFFF 的内存单元中写入数据的操作是无效的,因为这等于改写 只读存储器中的内容。
内存地址空间
最终运行程序的是CPU ,我们用汇编编程的时候,必须要从 CPU 角度考虑问题。 对CPU 来讲,系统中的所有存储器中的存储单元,都处于一个统一的逻辑存储器中,它的容量受CPU 寻址能力的限制。 这个逻辑存储器即是我们所说的内存地址空间。
对于初学者,这个概念比较抽象,我们在后续的课程中将通过一些编程实践,来增加感性认识。
[ 本帖最后由 旭阳 于 8-4-2009 09:26 PM 编辑 ] |
|
|
|
|
|
|
|
|
|
|

楼主 |
发表于 8-4-2009 09:46 PM
|
显示全部楼层
第二章 寄存器 (CPU 工作原理)
一个典型的 CPU (此处,我们讨论的不是某一具体的 CPU ) 由运算器,控制器,寄存器等器件构成,这些器件靠内部总线相连。
前一章所说的总线 ,相对于CPU 内部来说是外部总线。(意思就是说主板上连接去CPU的总线称之为外部总线,而CPU 内部也有连接内部各大小器件的总线)
内部总线实现CPU 内部各个器件之间的联系,外部总线实现了CPU 和主板上其它器件的联系。
简单的说,在CPU 中:运算器进行信息处理;寄存器进行信息存储;控制器控制各种器件进行工作;内部总线连接各种器件,在它们之间进行数据的传送。
对于一个汇编程序员来说,CPU 的主要部件是寄存器。 寄存器是CPU 中,程序员可以用指令读写的部件。程序员通过改变各种寄存器中的内容来实现对CPU 的控制。
不同的CPU ,寄存器的个数,结构是不相同的。 8086 CPU 有14 个寄存器,每个寄存器有一个名称。这些寄存器是:AX , BX , CX , DX , SI , DI , SP , BP , IP , CS, SS, DS ,ES ,PSW 。
我们不对这些寄存器进行一次性的介绍,在课程的进行中,需要用到哪个寄存器时再进行介绍。
[ 本帖最后由 旭阳 于 8-4-2009 09:53 PM 编辑 ] |
|
|
|
|
|
|
|
|
|
|

楼主 |
发表于 8-4-2009 11:13 PM
|
显示全部楼层
|
|
|
|
|
|
|
|
|
|

楼主 |
发表于 4-5-2009 09:46 PM
|
显示全部楼层
2.2 字在寄存器中的存储
出于对兼容性的考虑,8086 CPU 可以一次性处理两种尺寸的数据:
* 字节: 记为 byte ,一个 字节由 8个 bit (比特--二进制位)组成,可以存在 8 位寄存器中.
* 字 :记为 world ,一个字由两个字节组成,这两个字节分别称为这个字的高位字节和低位字节,如图 2.5 所示.

一个字可以存在一个 16位寄存器中,这个字的高位字节和低位字节自然就存在这个寄存器的高8 位寄存器和 低 8 位寄存器中.
如图 2.4 所示,一个字形数据 20000 ,存在 AX 寄存器中,在AH 中存储了它的高8位,在AL中存储了它的低8位。
AH 和 AL 中的数据,既可以看成是一个字型数据的高8位和低8位,这个字型数据的大小是:20000 ;又可以看成是两个独立的字节型数据,它们的大小分别是 78 和 32。
关于数制的讨论
任何数据,到了计算机中都是以二进制的形式存放的。 我们为了描述不同的问题,又经常将它们用其他的进制来表示。 比如图 2.4 中寄存器 AX 中的数据是 0100111000100000 ,这就是AX中的信息本身,我们可以用不同的逻辑意义来看待它。
我们可以将它看作一个数值,大小是 20000 。
当然,二进制数 0100111000100000 本身也可以表示一个数值的大小,但人类习惯的是十进制,用十进制 20000 表示可以使我们直观地感受到这个数值的大小。
我们知道十六进制数的一位相当等于二进制数的四位,如 0100111000100000 可表示成 4(0100),E(1110) , 2(0010) , 0(0000) 四位十六进制数。
由于一个内存单元可存放8位数据(8个 bit),CPU 中的寄存器又可存放n 个 8位数据。 也就是说,计算机中的数据大多是由1~N 个 8 位数据构成的。很多时候,需要直观地看出组成数据的各个字节数据的值,用十六进制来表示数据可以直观地看出这个数据是由哪些 8 位数据构成的。
比如 20000 写成 4E20 就可以直观地看出,这个数据是由 4E 和 20 两个8位数据构成的,如果 AX 中存放 4E20 ,则 AH 里是 4E ,AL 里是 20 。这种表示方法便于许多问题的直观分析。 在以后的课程中,我们多用十六进制来表示一个数据。
在以后的课程中,为了区分不同的进制,我们在十六进制表示的数据的后面加 H ,在二进制表示的数据后面加 B ,十进制表示的数据后面什么也不加。
如:我们可用3种不同的进制表示图2.4 中 AX 里的数据,十进制:20000,十六进制:4E20 H ,二进制:0100111000100000 B .
[ 本帖最后由 旭阳 于 10-5-2009 08:36 AM 编辑 ] |
|
|
|
|
|
|
|
|
|
|

楼主 |
发表于 10-5-2009 08:59 AM
|
显示全部楼层
2.3 几条汇编指令
我们可以通过汇编指令控制 CPU 进行工作,常用的汇编指令如表 2.1 所示。

我们看一下 CPU 执行表 2.2 中所列的程序段中的每条指令后,对寄存器中的数据进行的改变。

问题2.1
指令执行后,AX的数据为多少?思考后看分析。
分析:
程序段中的最后一条指令 add ax,bx ,在执行前 ax 和 bx 中的数据都为 8226 H ,相加后所得的值为:1004C H ,但是ax 为16 位寄存器,只能存放4位十六进制的数据,所以最高位的 1 不能在 ax 中保存 ,ax 中的数据为 044C H 。
[ 本帖最后由 旭阳 于 10-5-2009 09:10 AM 编辑 ] |
|
|
|
|
|
|
|
|
| |
本周最热论坛帖子
|