兰陵月 发表于 2016-3-22 00:39:06

汇编(8086)语言复习笔记【2016.3第2次】

第1章 基础知识【1】
1、汇编语言是直接在硬件上工作的语言。
2、编译器将汇编指令编译(“翻译”)成机器语言。
3、汇编语言由3类指令组成:
(1)汇编指令:机器码的助记符,有对应的机器码;【这是核心】
(2)伪指令:没有对应的机器码,由编译器执行,计算机并不执行。
(3)其他符号:如+、-、*、/等,由编译器识别,没有对应的机器码。
4、存储器存即内存(我把之称为广义内存,叫法不知是否妥当),此处内存不仅仅指大家所说的“内存条”,还包括中间处理单元内部的L1、L2Cache,一、二级缓存以及外部的内存,还包括显存等等。
5、对CPU来说,指令和数据并没有什么区别,都是二进制信息,CPU也只能看懂二进制信息。
6、一个存储单元(王爽书中也有“内存单元”的叫法)就是一个字节(Byte),一个字节有8位(Bit)。
1Byte=8Bit    1KB=1024B    1MB=1024KB    1GB=1024MB   1TB=1024GB
7、CPU要对存储器进行读写操作,必须有几个条件:
(1)存储单位的地址(地址信息):即要知道在什么地方做。
(2)器件的选择,读或写的命令(控制信息):即要知道要做什么,是要读还是写?对谁读?对谁写?。
(3)读或写的数据(数据信息):即要知道拿什么去做,读什么东东?写什么东东?
8、信息要靠什么传送?当然是导线(印刷电路),这些导线作用性质相同的集合在一起就是总线,根据上述第7点,总线从逻辑上就分为3类:地址总线、控制总线、数据总线。从地址总线传过来的信息,CPU就当做地址来做相关处理。从控制总线传过来的信息,CPU就当做控制信息处理。从数据总线传过来的信息,CPU就当做数据来处理。CPU怎么看待这些二进制信息,主要是依靠从哪类总线传过来的进行判断(设计CPU的大大就是这么设计的,所以咱们这么理解)
9、地址总线:
一个CPU有N根地址总线,则可以说这个CPU的地址总线宽度为N,这样CPU最多可以寻找2的N次方个内存单元(字节)。
8086CPU有20根地址总线,地址总线宽度为20,最多可以寻址2的20次方个内存单元。即可寻址1048576字节,即1024KB,即1M。即可以访问1M的内存空间,实际上除了被固定占有的ROM外,我们用户能用到的当然没有达到1M。
10、数据总线
一根线只有两个状态,即高电平和低电平。所以一根线只能传送1或0,也就说只能传送1位(Bit)。所以数据总线有多少根,每次就能传送多少位。8088CPU数据总线8根,所以其宽度为8,因此一次只能传送8Bit,即1个字节。8086CPU数据总线16根,其宽度为16,因此一次能传送16Bit,即2个字节。
11、控制总线
是一些不同控制线的集合,有多少根控制总线,就能控制多少个设备。
12、接口卡
CPU不能直接控制外部设备,只能通过向该设备的接口卡发送命令,接口卡再根据CPU的命令控制外设进行工作。
13、内存地址空间
CPU在逻辑上将所有存储器看成一个连续的线性排列空间。

兰陵月 发表于 2016-3-22 00:39:37

第2章寄存器【1】
1、内部总线:CPU内部各个器件之间的联系。外部总线:CPU和主板上其他器件的联系。
2、CPU内部:运算器进行信息处理;寄存器进行信息储存;控制器控制各种器件进行工作;内部总线连接各种器件,在它们之间进行数据的传送。
3、8086CPU有14个寄存器:AX,BX,CX,DX,SI,DI,SP,BP,IP,CS,SS,DS,ES,PSW
4、通用寄存器:AX,BX,CX,DX。这4个寄存器都是16位的,每个寄存器均可分为两个独立的8位寄存器来用。
AX:AH、AL;
BX:BH、BL;
CX:CH、CL;
DX:DH、DL。
5、1个字节可以存储在8位寄存器中;1个字可以存储在16位寄存器中,高位字节放寄存器的高8位;低位字节放寄存器低8位。
6、mov指令是传送8位还是传送16位,是根据操作数里的寄存器位数来决定的。如果操作数里涉及的寄存器是8位,则传送1个字节,如果操作数里涉及的寄存器是16位的,则传送1个字。同样ADD指令也是一样。
7、如果CPU要访问某个内存单元,必须知道它的物理地址,对CPU来说,所有的内存(电脑里各种各样的内存,不仅仅指内存条的那个内存)集合起来构成一个线性空间(CPU看到的是一个线性空间),每一个内存单元在这个线性空间中都有唯一的地址,这个地址叫做物理地址。
8、16位8086CPU的特点:
(1)运算器一次最多可以处理16位的数据;
(2)寄存器的最大宽度为16位;
(3)寄存器和运算器之间的通路为16位。
9、8086CPU的地址总线有20位,有1MB的寻址能力,但是CPU结构又是16位的,如果不做其他处理的话,CPU能寻址的空间只有64KB,其他1MB-64KB的空间CPU根本就看不到,这将造成极大的浪费。如何才能让CPU能够寻址1MB空间呢?
(1)8086CPU采用在内部用两个16位地址合成的方法形成一个20位的物理地址。具体表现为用地址加法器来进行合成。
(2)这两个16位地址中,一个叫做段地址,一个叫做偏移地址。
(3)最终:物理地址=段地址X16+偏移地址。段地址X16的实际表现位16位物理地址左移1位。
10、“段”的概念,内存并没有在物理上划分为一个一个的段,这里说的段,实际上的CPU在寻址时在逻辑上进行的划分。可以根据需要,将地址连续、起始地址为16的倍数、最大不超过64KB的一组内存单元定义为一个段。
第2章寄存器【2】
11、段寄存器:8086CPU有4个段寄存器,分别是CS、DS、SS、ES。
12、CS和IP:CS为代码段寄存器,IP为指令指针寄存器。任意时刻,CPU将CS:IP指向的内容当作指令来执行。按照物理地址的计算方法,可以得知当前要执行的指令的地址位:CS * 16 + IP。要让CPU执行我们写的代码,必须把CS:IP指向我们编写的要执行的第一条指令的首地址(即代码第一条所存放的物理地址)。
13、8086CPU加电启动或复位后,CS被设置为FFFFH,IP被设置为0000H。因此8086PC机开机后执行的第一条指令的物理地址为FFFF0H。
14、JMP指令可以修改CS和IP,实际上就是跳转。实现方法为“JMP 段地址:偏移地址”,如果只是单独改变IP的值,可以采用“JMP 某一合法寄存器”的方法,该合法寄存器是指通用寄存器。
15、DEBUG的使用方法:
R: 查看、改变寄存器的内容:查看,直接输入R;改变寄存器数据:R 某寄存器
D: 查看内存中的内容
E: 改写内容中的内容
U:将内存中的机器指令翻译成汇编指令
T: 执行一条机器指令
A: 以汇编指令格式在内存写入一条机器指令;
P: 中断当前正在执行的程序。

兰陵月 发表于 2016-3-22 00:40:10

第3章寄存器(内存访问)【1】
1、内存中字的存储:字单元,即存放一个字型数据(16位)的内存单元,由两个地址连续的内存单元组成。高地址内存单元中存放字型数据的高位字节,低地址内存单元中存放字型数据的低位字节。
2、DS和:DS通常用来存放要访问数据的段地址,表示要存放的数据的偏移地址。
3、不能用MOV指令直接将数据传入段寄存器,例如MOV DS,0300H,这是错误的,为什么?CPU生下来就这样。
4、MOV指令是传送1字节还是传送1个字,由操作数中的寄存器大小决定,涉及的寄存器为8位,则传送一个字节,涉及的寄存器为16位,则传送一个字。【貌似前面已经说过了】
5、MOV指令:数据>寄存器;寄存器>寄存器;内存单元>寄存器;寄存器>内存单元;寄存器>段寄存器;段寄存器>寄存器;段寄存器>内存单元;内存单元>段寄存器。【ADD和SUB指令不能对段寄存器进行操作】。
6、数据段:数据段和指令段一样,在CPU看来都是二进制信息,如何要CPU将之认为是数据呢?可以用DS存放数据段的段地址,段内的数据可以用偏移地址来访问。一个字型数据占据两个内存单元。
第3章寄存器(内存访问)【2】
7、栈:一种具有特殊的访问方式的存储空间,它的特殊性就在于,最后进入这个空间的数据,最先出去。
栈的两个基本操作:入栈(PUSH)、出栈(POP),入栈和出栈都以字为单位进行。
入栈(PUSH):将一个新的元素放到栈顶。
出栈(POP):从栈顶取出一个元素。
栈顶的元素总是最后入栈,需要出栈时,又最先被从栈中取出。这种操作规则被称为:LIFO(Last In First Out,后进先出)。
8、CPU如何知道某段空间被当作栈来使用?PUSH和POP时,如何知道哪个单元是栈顶单元呢?
(1)SS寄存器存放栈顶单元的段地址,SP寄存器存放栈顶单元的的偏移地址。
(2)任意时刻:SS:SP指向栈顶单元元素。
9、PUSH执行说明:
(1)SP=SP-2;(2)将寄存器内容(或立即数、内存单元中的内容)送入SS:SP。
8086CPU中,入栈时,栈顶从高地址向低地址方向增长。
10、POP执行说明:
(1)SS:SP指向的内容送入寄存器(或内存单元);(2)SP=SP+2。
11、当一个栈为空栈时,SS:SP指向栈空间最高地址单元的下一个单元。
12、POP后,被取出的内存单元内容仍然在该地址存在,但此时该地址已经不是栈中的地址,所以用栈的方式去访问的话就访问不到了。
第3章寄存器(内存访问)【3】
13、栈越界的问题,8086CPU不保证我们对栈的操作不回超界。因此,我们在编程的时候要自己操心栈顶越界的问题。要根据可能用到的最大空间,来合理安排栈的大小。
14、PUSH和POP
PUSH:寄存器、段寄存器、内存单元
POP:寄存器、段寄存器、内存单元
15、PUSH和POP指令也是内存传送指令,与MOV不同的是,它们同时还改变SP的值。同时,MOV指令只需要一步,而PUSH和POP指令需要两步。
16、栈段,意义同以前的代码段、数据段。同时,这也只是我们编程时的安排,CPU并不认识所谓的“栈段”。栈段既然也是段,毫无疑问最大不超过64KB。
17、一段内存,既可以是代码的存储空间,又可以是数据的存储空间,还可以是栈空间,当然也可以什么都不是。关键在于CPU中寄存器的设置,即CS、IP、SS、SP、DS的指向。
18、DEBUG的T命令在执行修改寄存器SS的指令时,下一条指令也紧接着被执行。

Angel丶L 发表于 2016-3-22 01:22:18

在下服了

兰陵月 发表于 2016-3-22 12:50:12

Angel丶L 发表于 2016-3-22 01:22
在下服了

其实发上来的原因是因为有的一知半解,有的不知道是否错误,如果鱼油们能发现错误,就是对我最大的指教。{:10_323:}说穿了就是偷懒{:10_275:}

兰陵月 发表于 2016-3-22 12:52:44

第4章第一个程序

1、一个汇编语言程序从写出到最终执行的过程:

(1)编写汇编源程序;

(2)对源程序进行编译连接;

编译连接后称为可执行文件,可执行文件分为程序和相关的描述信息。

(3)执行可执行文件的程序。将程序载入内存,并进行相关的初始化,然后由CPU开始执行。

2、源程序中有两种指令:汇编指令和伪指令。

3、一个有意义的汇编程序至少要有一个段,这个段用来存放代码。

4、segment和ends:段开始和段结束。

5、end:程序结束。

6、assume:假设的意思,将段与某寄存器关联起来。

7、源程序与程序的区别表述:源程序包含所有代码,程序仅指计算机执行、处理的指令或数据。

8、标号:一个标号代表一个地址(最终被编译、连接程序处理为一个段的段地址)

9、程序返回

mov ax,4c00H

int 21H

10、PE文件:可执行可移植文件。

11、DOS系统是一个单任务操作系统,多任务系统,涉及消息机制和时间片等概念。

12、PSP(程序前缀区):DOS加载程序时,会在程序装入的前面加一段数据区,称为PSP,即程序前缀区。程序前缀区的大小为256个字节,即100H,用DEBUG调试时,PSP地址为DS:0,程序的物理地址为DS+10H:0。

兰陵月 发表于 2016-3-22 12:53:29

第5章和loop

1、在文本编辑器中类似mov ax,、mov ax,,我们的本意可能是把段地址ds,偏移为0的地址内的内容传送到ax中,但实际上程序被masm编译时,、等于0、1。因此为了避免这种错误情况发生,编程时我们要做相应的处理。要实现把段地址ds,偏移为0的地址内的内容传送到ax中,可以这样做。mov bx,0、mov ax,,这样来实现。当然如果还是要采取、的方式达到正确的效果,则必须在、前面显式的加上段寄存器DS。比如,mov ax,ds:或者mov ax,ds:这样也可以达到正确的效果。

2、inc 某寄存器。指令意思是自加1。

3、loop与CX搭配使用。首先CX自减1,再判断CX是否为0,如果为0,向下执行,如果不为0,则跳转到标号处执行。

4、CX和LOOP指令配合来实现循环功能:

(1)CX中存放循环次数;

(2)LOOP指令中的标号所标识的地址要在前面;

(3)要循环执行的程序段,要写在标号和LOOP指令的中间。

5、DEBUG中,遇到循环,可以使用P命令,直接执行到循环结束,即loop的下一句。如果要执行偏移地址处,也可以使用g命令:g 偏移地址。

6、汇编源程序中,数据不能以字母开头,16进制的以字母开头的数据在汇编源程序中应在第一个字母前加0。

7、编写程序选择寄存器时,首先要考虑寄存器得到的结果是否会越界,形成这样一个良好的习惯,再要考虑赋值的正确性。

8、出现在访问内存单元的指令中,用于显式地指明内存单元的段地址的DS:、CS:、SS:、ES:,在汇编语言中称为段前缀。【前面还有一个名词:程序前缀区】

9、一段安全的空间:如需向内存空间写入内容,则被写入的内存空间不应存放系统或其他程序的数据或代码,否则写入操作很可能引发错误。DOS方式下,一般情况,0:200—0:2FF空间中没有系统或其他程序的数据或代码。可以利用上述这段256个字节的空间。

10、mov用在寄存器之间传送数据的指令是2个字节,用在寄存器和立即数之间是3个字节。

兰陵月 发表于 2016-3-22 12:54:01

第6章包含多个段的程序

1、程序取得所需空间的方法有两种:一是在加载程序的时候为程序分配;二是程序在执行的过程中向系统申请。

2、DW,即“define word”,定义字型数据。

3、end后面可以跟程序入口点。

4、段的名字在编译之后直接变成一个地址。

5、所谓“代码段”、“数据段”、“栈段”完全是我们自己的安排,CPU并不知道。

6、一个段(指程序中用segment指明的段)最小为16字节。低于16字节仍然以16字节进行内存分配。

7、没有指明程序开始处,即end结束语后没有跟标号的,程序自动顺序执行。

8、可能错误:PUSH和POP都是以字节为单位进行操作,因此当BX作为偏移地址时,自加或者自减都要操作2次,或者采用add BX,2(SUB BX,2)的方式才会正确。

9、可能错误:mov不能在内存单元和内存单元之间操作,如mov ,是错误的。

乍泄1996 发表于 2016-3-26 18:32:39

马一下!!感觉考试会很有用{:5_109:}

兰陵月 发表于 2016-3-27 09:38:26

第7章   更灵活的定位内存地址的方法
1、and和or指令:and可将操作对象的相应位置0;or可将操作对此昂的相应位置1;
2、不管字母大小写,只要将其二进制形式的第5位变为1,则字母均会变为小写字母;只要将其二进制形式的第5位变为0,则字母均会变为大写字母。
3、可以写成:、200、.200。第三种方式.200在DOSbox0.74虚拟环境中显示语法错误。前面两种可以通过。
4、SI和DI功能与BX相近,SI和DI不能分成两个8位寄存器来使用。
5、二重循环问题要考虑到外层循环次数压栈的问题。
第8章 数据处理的两个基本问题
1、描述性符号:reg和sreg,reg表示寄存器,sreg表示段寄存器。
2、只有bx、si、di、bp才能用在“[…]”中进行内存单元的寻址。
3、bx、bp可以分别和si、di搭配使用。bx、bp不能组合使用。、的表述方法是错误的。
4、如果没有显式给出段寄存器,则bx默认和ds搭配,bp默认和ss搭配。
5、数据处理分三类:读取、写入、运算。要处理的数据放在三个地方:CPU内部、内存、端口。
6、汇编中三个概念来表达数据的位置:立即数、寄存器、段地址:偏移地址。
7、寻址方式:
(1)直接寻址:指令 立即数
(2)寄存器间接寻址:指令[寄存器](此处寄存器可以bx、si、di、bp或它们的合法组合)
(3)寄存器相对寻址:指令[寄存器+立即数]
(4)基址变址寻址:指令[寄存器+寄存器]
(5)相对基址变址寻址:指令[寄存器+寄存器+立即数],可用于结构化数据的访问。
8、8086处理两种尺寸的数据:byte、word。
9、8086通过两种方式指令数据的尺寸:
(1)通过寄存器的方式,如指令后寄存器为16位,则要处理的数据为word型,如指令后寄存器为8位,则要处理的数据为byte型。(隐性指明)
(2)在没有寄存器名存在的情况下,用操作符X ptr 指明内存单元的长度,X在汇编指令中可以为word或byte。(显性指明)
10、PUSH指令只进行字节操作(前面章节已经说过)。
11、div指令
(1)除数:有8位和16位两种,在一个reg或内存单元中。
(2)被除数:默认放在AX或DX和AX中,如果除数为8位,被除数则为16位,默认在AX中存放;如果除数为16位,被除数则为32位,在DX和AX中存放,DX存放高16位,AX存放低16位。
(3)结果:如果除数为8位,则AL存储除法操作的商,AH存储除法操作的余数;如果除数为16位,则AX存储除法操作的商,DX存储除法操作的余数。
12、DIV格式:div reg    div 内存单元
13、伪指令DD:定义双字节。
14、DUP与DB、DW、DD配合来重复进行数据定义。

poiulp 发表于 2016-3-28 13:34:12

呵~ 你就这么发笔记?!挺你!

兰陵月 发表于 2016-3-28 16:35:04

poiulp 发表于 2016-3-28 13:34
呵~ 你就这么发笔记?!挺你!

{:10_275:}{:10_275:}
只是个新鱼油,不能发日志,现在可以发日志了。{:10_275:}

兰陵月 发表于 2016-3-28 16:35:37

poiulp 发表于 2016-3-28 13:34
呵~ 你就这么发笔记?!挺你!

是不是感觉我太奔放,哈哈哈啊哈哈哈哈哈{:10_332:}

兰陵月 发表于 2016-3-29 13:05:57

第9章转移指令的原理
1、转移指令:可以修改IP(段内转移),或同时修改CS和IP的指令(段间转移)。段内转移:IP修改范围-128~127,短转移;IP修改范围-32768~32767,近转移。
2、offset:取得标号的偏移地址,由编译器处理的符号。
3、jmp short 标号:该指令所对应的机器码中,并不包含转移的目的地址,而包含的是转移的位移。
(IP)=(IP)+8位位移,8位位移范围:-128~127,用补码表示(正数的补码是原数,负数的补码为取反+1)
4、jmp near ptr实现的是段内近转移。
(IP)=(IP)+16位位移,16位位移范围:-32768~32767,用补码表示
5、jmp far ptr 标号:段间转移,用标号的段地址和偏移地址修改CS和IP。
6、jmp 寄存器:用寄存器值修改IP
7、jmp word ptr 内存单元地址(段内转移):用内存中的一个字来修改IP
8、jmp dword ptr 内存单元地址(段间转移):用内存中的高地址字修改CS,低地址字修改IP。
(CS)=(内存单元地址+2)
(IP)=(内存单元地址)
9、可能出现的错误:mov ,立即数,这种表述编译器会报错,因为没有提供传送的数据长度。应该为mov word ptr ,立即数.(word可以为byte或者word)。根据检测点9.2的出题,因为mov 中间没有指明数据长度,因此后面填写立即数的答案都是错误的。所以应该是寄存器类型才可(寄存器的类型决定了数据长度,同样反证了mov指令必须要指明数据长度)。
10、jcxz指令:有条件转移指令(所有的有条件转移指令都是短转移,对应的机器码中含有位移,而不是目的地址,对IP的修改范围:-128~127)
11、检测点9.3应当仔细多次再次理解其跳出循环的思路并予以借鉴。反推思路:如果没有发现为0的字节,则不断循环寻找下一个字节,如果发现了为0的字节,则应该跳出循环,如果跳出循环呢,则CX-1=0,而程序中此时CX已经为0,那么如果不作处理,CX-1肯定不会等于0,因此必须要作处理,让CX=1,这样循环就会跳出,也才能正常实现程序的功能。这就是“inc cx”的涵义。【绕的好深啊】
12、要结合书本附注3充分理解masm对“jmp short 标号”的处理。【很重要】
页: [1]
查看完整版本: 汇编(8086)语言复习笔记【2016.3第2次】