我之所以要学习汇编,不是为了用那些难读的语句做程序,而是因为我觉得只有掌握了这些知识才能在
开发中将需要提高性能部分的代码优化得更好,甚至可以通过嵌入汇编来最大限度得提高性能。
我还想说的是,我觉得现在完全用汇编来做普通的程序除了能炫耀自己的汇编技术以外没有什么其他作
用。真正需要用汇编写程序的地方是因为种种原因不得不用汇编的,如果能用高级语言谁用汇编啊。
第一章 基础知识
1.1 机器语言
机器语言复杂难懂,难于调试,可移植性差(废话)
1.2 汇编语言的产生
汇编是机器码的助记符,是机器语言便于记忆、理解的书写格式
1.3 汇编语言的组成
汇编语言由3类指令组成
1. 汇编指令,机器码的助记符
2. 伪指令,编译器的指令,没有对应的机器码(跟宏有点相似)
3. 其他符号,+、-、*、/等,由编译器识别,没有对应的机器码。
1.4 存储器
总之就是说存储器很重要。
记得以前看过一份教程作了一个比喻,CPU以寄存器为指挥部,以内存为战场,指挥着一场战争。
我想如果这样比喻的话把硬盘比喻成后勤补给不知道恰当不恰当...
1.5 指令和数据
内存中的二进制信息计算机可以将其理解为数据也可以理解为指令,也就是说这些信息直接来看是
没有具体意义的,必须得在执行中才有具体意义。
1.6 存储单元
存储单元从0开始顺序编号,一个存储单元存储一个字节,一字节8位(还是废话)。
计量单位: 1KB = 1024B 1MB=1024KB 1GB=1024MB 1TB=1024GB(又是废话)
1.7 CPU对存储器的读写
CPU要进行数据读写,必须和外部器件进行3类信息的交互
1. 存储单元的地址(地址信息)
2. 器件的选择,读或写的命令(控制信息)
2. 读或写的数据(数据信息)
1.8 地址总线
CPU通过地址总线来指定存储器单元,地址总线上能传送多少个不通的信息,CPU就可以对多少个存
储单元进行寻址(即CPU的寻址能力)。
CPU的寻址能力=2的"CPU地址总线宽度"次方
1.9 数据总线
数据总线的宽度决定了CPU与外界的数据传输数度
1.10 控制总线
控制总线的宽度决定了CPU对外部器件的控制能力,有多少根控制总线就意味着CPU提供了对外部器
件的多少种控制(为什么不是取决于多少种状态呢?可能是硬件原因吧)。
1.1~1.0 小结&习题
小结不抄了,跟上面的差不多;习题都是写计算题,套上面的公式就行了。
1.11 内存地址空间(概述)
一个CPU可寻址的内存单元数量就是这个CPU得内存地址空间的大小。
1.12 主板
主板就是主板 - -||
1.13 接口卡
直接插在主板上的卡-___-||
1.14 各类存储器芯片
1. 随机存储器(RAM)内存
2. 装有BIOS的ROM,如主板BIOS ROM、显卡BIOS ROM....
3. 接口卡上的RAM,如显卡
1.15 内存地址空间
上面的各种存储器都和CPU总线相连,CPU对它们进行读或写的时候都通过控制线发出内存读写命令,
从CPU的角度来看他们是一个由若干存储单元组成的逻辑存储器,这个逻辑存储器就是这里指的内存空间
内存地址空间的大小受CPU地址总线宽度的限制(具体来说就是CPU的寻址能力)。
内存地址空间分配情况根据不同的硬件系统而不同。
8086内存地址空间分配情况
--------------------------
00000 | |
| |
| |
| |
| 主存储器地址空间(RAM) |
| |
| |
| |
9FFFF | |
|--------------------------|
A0000 | |
| |
| 显存地址空间 |
| |
BFFFF | |
|--------------------------|
C0000 | |
| |
| 各类ROM地址空间 |
| |
| |
FFFFF --------------------------
图比例肯定不对啦,将就着看吧。
第一章总结
这一章是基础知识,对很多人来说可以不看,不过还是看看比较好,最好不要对这些知识模棱两可,
这样对于系统化的学习这本书(或者说是汇编语言)有帮助。
下一章预览
第二章 寄存器(CPU工作原理)讲的是CPU中的几种寄存器,大体预览了一下。我的感觉是这章很重要,
内容也会比第一章多,而且要记的东西也多- -|||。不过比第一章更靠近主题了,应该也会变得更有趣(
反问自己一下,死记硬背有趣吗?汗...)。
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/songyx0/archive/2006/09/29/1306161.aspx
第二章 寄存器(CPU工作原理)
对于一个汇编程序员来说,CPU 中的主要部件是寄存器。寄存器是CPU 中程序员可以用指令读写
的部件。程序员通过改变各种寄存器中的内容来实现对CPU的控制。
不同的CPU,寄存器的个数、结构是不同的。8086CPU有14各寄存器,每个寄存器有一个名称。这些寄存器是:AX、BX、CX、DX、SI、DI、SP、BP、IP、CS、SS、DS、ES、PSW。
2.1 通用寄存器
8086CPU 的所有寄存器都是16位的。AX、BX、CX、DX四个寄存器通常用来存放一般性的数
据,被称为通用寄存器。
寄存器的逻辑结构
寄存器
______________________________________/\_______________________________________
/ \
15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00
-------------------------------------------------------------------------------
| ## | ## | ## | ## | ## | ## | ## | ## | ## | ## | ## | ## | ## | ## | ## | ## |
-------------------------------------------------------------------------------
为了保持和上一代的8位CPU兼容,8086CP U的AX、BX、CX、DX四个寄存器都可以分为两个可
独立使用的8位寄存器来用:
# AX可分为AH和AL
# BX~~~BH~BL
# CX~~~CH~CL
# DX~~~DH~DL
逻辑结构图:
?X
______________________________________/\_______________________________________
/ \
15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00
-------------------------------------------------------------------------------
| ## | ## | ## | ## | ## | ## | ## | ## | ## | ## | ## | ## | ## | ## | ## | ## |
-------------------------------------------------------------------------------
7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
\__________________ __________________/ \__________________ __________________/
\/ \/
?H ?L
(图画得不错吧?^_^)
2.2 字在寄存器中的存储
出于对兼容性的考虑,8086CPU可以一次性处理两种尺寸的数据:
# 字节: 记为byte,一个字节由8个二进制位组成,可以一存在8位寄存器中
# 字: 记为word,一个字由两个字节组成,这两个字节分别成为这个字的高字节和低字节
在关于数制的讨论中说明了二进制、十进制、十六进制的特点,我觉得十六进制是介于二进制
和十进制之间的数制,十六进制和二进制的转换方便,而和十进制的转换也很方便。
2.3 几条汇编指令
汇编不区分大小写。
这一小节中列出了5条汇编指令、其意义以及高级语言的语法描述。如下:
汇编指令 控制CPU完成的操作 用高级语言的语法描述
----------------------------------------------------------------------------------
mov ax,18 将18送入寄存器AX AX = 18
mov ah,78 ~19~~~~~AH AH = 78
add ax,8 将寄存器AX中的数据加上8 AX = AX + 8
mov ax,bx ~~~~BX~~~~送入寄存器AX AX = BX
add ax,bx 将AX和BX中的数值相加,结果存在AX中 AX = AX + BX
==================================================================================
接着列出了6条指令及其运算结果:(原AX、BX中的值都为0000H):
程序段中的指令 执行指令后AX中的数据 执行指令后BX中的数据
----------------------------------------------------------------------------------
mov ax,4E20H 4E20H 0000H
add ax,1406H 6226H 0000H
mov bx,2000H 6226H 2000H
add ax,bx 8226H 2000H
mov bx,ax 8226H 8226H
add ax,bx ? 8226H
==================================================================================
上表中程序最后一条指令:"add ax,bx",ax、bx相加,即:8226H + 8226H。相加后所得值
为: 1044CH,但是ax为16位寄存器,只能存放4位十六进制的数据,所以最高位"1"不能在AX中保
存,被截掉,AX中的数据就成了044CH了。
再看下面的程序
程序段中的指令 执行指令后AX中的数据 执行指令后BX中的数据
----------------------------------------------------------------------------------
mov ax,001AH 001AH 0000H
mov bx,0026H 001AH 0026H
add al,bl 0040H 0026H
add ah,bl 2640H 0026H
add bh,al 2640H 4026H
mov ah,0 0040H 4026H
add al,85H 00C5H 4026H
add al,93H ? 4026H
==================================================================================
程序段中的最后一条指令"add al,93H",al中的数据85H与93H相加值为158H,这时要把
158H存入8位寄存器al中,但8位寄存器只能存放两位十六进制的数据,所以最高位丢失,ax中的
数据为0058H。(实际上不是真的丢弃这个进位值,在后面的课程中将继续讨论这个问题)。
不要想当然的以为al是ax的低8位进位值会存储在ah中,CPU只把al当作8位寄存器来用。
在数据传送或运算是,要注意指令的两个操作对象的位数必须一致。
测试点2.1
(1) 全是程序求值,仔细看了这一小节就能做出来。
(2) 用目前学过的汇编指令(即add、mov),最多用4条指令,编程计算2的4次方。
mov al,2;初始化al,al=2
add al,al;al=4
add al,al;al=8
add al,al;al=16
2.4 物理地址
这一章看上去都应该记住,我就都抄上来了。
CPU访问内存单元时,要给出内存单元的地址。所有的内存单元构成的存储空间时一个一维的
线性空间,每一个内存单元在这个空间中都有位移的地址,我们将这个唯一的地址称为物理地址。
CPU通过地址总线送入存储器的必须是一个内存单元的物理地址。在CPU向地址总线上发出物
理地址之前,必须在内部先形成这个物理地址。不通的CPU可以有不通的形成物理地址的方式。
2.5 16位结构的CPU
8086是16位机,也可以说8086是16位结构的CPU。
16位结构CPU具有下面几个方面的结构特征:
# 运算器一次最多可以处理16位的数据;
# 寄存器的最大宽度为16位;
# 寄存器合运算器之间的通路为16位。
也就是说在8086内部能够一次性处理、传输、暂时存储的信息的最大长度是16位的。内存单
元的地址在送上地址总线之前,必须在CPU中处理、传输、暂时存放,对于16位CPU,能一次性处
理、传输、暂时存储16位的地址。
2.6 8086CPU给出物理地址的方法
8086CPU有20位地址总线,可传送20位地址,达到 1MB的寻址能力,8086CPU又是16位结构,
在内部一次性处理、传输、暂时存储的地址为16位。从 8086CPU的内部结构来看,如果将地址从
内部简单的发出,那么它只能送出16位的地址,表现出的寻址能力只有64KB。
8086CPU采用一种在内部用两个16位地址合成的方法来形成一个20位的物理地址。
----------------------------------------------
| -------------- ------------ |
|| |----------------| ||
|| | 段基址-> | ||
|| |----------------| ||
|| | | 地址加法器 ||
|| |----------------| ||
|| | 偏移地址-> | ||
|| |----------------| ||
|| | ------------ |
|| | | | |
|| | |物| |
|| | |理| |
|| | |地| |
|| | |址| |
|| 其他部件 | |||| |
|| | |\/| |
|| | | | | ------------
|| | ------------- | 20位地址总线 | |
|| | | |-------------------| |
|| | | | 物理地址-> | |
|| | | |-------------------| |
|| | | || | |
|| | | 输入输出 |-------------------| |
|| | | | 数据总线 | 内存 |
|| | | 控制电路 |-------------------| |
|| | | || | |
|| | | |-------------------| |
|| | | | 控制总线 | |
|| | | |-------------------| |
| -------------- ------------- | | |
---------------------------------------------- ------------
如上图所示,当8086CPU要读写内存时:
(1) CPU中的相关部件提供两个16位的地址,一个成为段地址,另一个成为偏移地址;
(2) 段地址和偏移地址通过内部总线传入一个称为地址加法器的部件;
(3) 地址加法器将两个16位地址合并为一个20位的物理地址;
(4) 地址加法器通过内部总线将20位物理地址送入输入输出控制电路;
(5) 输入输出控制电路将20位物理地址送上地址总线;
(6) 20位物理地址被地址总线传送到存储器。
物理地址计算公式:“物理地址=段地址×16+偏移地址”。
例:CPU要访问地址为123C8H的内存单元,此时地址加法器的工作过程如下:
(1) 相关部件提供段地址(1230H)和偏移地址(00C8H)
(2) 段地址和偏移地址送入
(3) 段地址×16(=12300H)
(4) 段地址×16+偏移地址,得出物理地址(123C8H)
(5) 输出物理地址(123C8H)
由段地址×16引发的讨论:
段地址×16 有一个更为常用的说法是左移4位。计算机中的所有信息都是以二进制的形式存
储的,段地址当然也不例外。“左移4位”中的位,指的是二进制位。
通过一系列例子及进一步思考得出一个结论: 一个X进制的数据左移1位,相当于×X。
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/songyx0/archive/2006/09/29/1306182.aspx
共0评论