汇编语言学习笔记(一)
2017-10-20 21:26
351 查看
/*--------------------------------------------------------------------------------------------分割线 基础知识--------------------------------------------------------------------------------------------------*/
程序猿们用汇编指令编写汇编源程序;汇编指令是机器指令的助记符。每一个CPU都有自己的汇编指令集。
指令和数据是应用上的概念。在内存或磁盘上,指令和数据没有任和区别,都是二进制信息。CPU在工作的时候,把有的信息看作指令,有的信息看作数据,为同样的信息赋予不同的意义。
CPU传输的电信号通过导线来传送。总线从物理上来讲,是一根根导线的集合。根据传送信息的不同,总线从逻辑上分为三类:地址总线,数据总线和控制总线。
地址总线:一个CPU有N根地址线,则可以说这个CPU的地址总线的宽度为N。这样的CPU最多可以寻找2的N次方个内存单元。(寻址能力)
8086的地址总线宽度为20,可以定位2^20个内存单元,则8086PC的内存地址空间大小为1MB,同理,80386CPU的地址总线宽度为32,则内存地址空间最大为4GB。
数据总线:8根数据总线一次可以传输一个字节,16根数据总线一次可以传输两个字节。8086CPU的数据总线宽度为16,8088CPU的数据总线宽度为8。(一次数据传送数量)
控制总线:CPU对外部器件的控制是通过控制总线来进行的。控制总线是个总称,控制总线是一些不同控制线的集合。有多少根控制总线,就意味着CPU提供了对外部器件的多少种控制。(控制能力)
/*--------------------------------------------------------------------------------------------分割线 寄存器------------------------------------------------------------------------------------------------------*/
8086CPU有14个寄存器,分别是:
AX,BX,CX,DX,SI,DI,SP,BP,IP,CS,SS,DS,ES,PSW.
这些寄存器都是16位的,可以放两个字节。
AX,BX,CX,DX用来存放一般性的数据,称为通用寄存器。为了兼容上代的CPU,这四个寄存器又都可以分为两个独立使用的8位寄存器:
AX:AH,AL; BX:BH,BL;CX:CH,CL;DX:DH,DL.
AX的低八位(0-7位)构成了AL寄存器,高八位(8-15位)构成了AH寄存器。AL产生的进位会丢失,而不会存储在AH中。
在写汇编指令或一个寄存器的名称时不区分大小写。
在进行数据传送或运算时,要注意指令的两个操作对象的位数应当是一致的。
8086是16位机:
1.运算器一次最多可以处理16位的数据;
2.寄存器的最大宽度为16位;
3.寄存器和运算器之间的通路为16位。
内存单元的地址在送上总线之前,必须在CPU中处理、传输、暂时存放,对于16位CPU,能一次处理、传输、暂时存储16位的地址。
因为8086有20位地址总线,如果将地址从内部简单的出发,那么它只能传送16位的地址。
8086CPU采用一种在内部用两个16位地址合成的方法来形成一个20位的物理地址。
物理地址=段地址*16+偏移地址
本质:CPU访问内存时,用一个基础地址(段地址*16)和一个相对于基础地址的偏移地址相加,给出内存单元的物理地址。
段地址*16必然是16的倍数,因此一个段的起始地址也一定是16的倍数;偏移地址为16位,16位地址的寻址能力为64KB,所以一个段的长度最大为64KB.(内存并没有分段,段的划分来自于CPU)
8086有4个段寄存器:CS,DS,ES,SS.
CS和IP寄存器指示了CPU当前要读取指令的地址。CS:代码段寄存器。IP:指令指针寄存器。
8086机中,任意时刻,CPU将CS:IP指向的内容当作指令执行。
8086的工作过程可简化如下:
1.从CS:IP指向的内存单元读取指令,读取的指令进入指令缓冲器;
2.IP=IP+所读取指令的长度,从而指向下一条指令;
3.执行指令。转到步骤1,重复这个过程。
在8086CPU加电位启动或复位后(即CPU刚开始工作时)CS和IP被设置为CS=FFFFH,IP=0000H,即在8086机刚启动时,CPU从内存FFFFH单元中读取指令执行,FFFF0H单元中的指令是8086机开机后执行的第一条指令。
指令和数据没有区别,那么CPU根据什么将内存中的信息看作指令?
CPU将CS:IP指向的内存单元中的内容看作指令。如果说,内存中的一段信息曾被CPU执行的话,那么它所在的内存单元必然被CS:IP指向过。
mov指令(传送指令),无法设置CS,IP的值。可通过jmp指令修改:
jmp 2AE3:3 执行后:CS=2AE3H,IP=0003H,CPU将从2AE33H处读取指令。
jmp 段地址:偏移地址
jmp 某一合法寄存器 可以仅修改IP的值,如:
jmp ax 执行指令前:ax=1000H,CS=2000H,IP=0003H
执行指令后:ax=1000H,CS=2000H,IP=1000H
/*--------------------------------------------------------------------------------分割线 寄存器(内存访问)----------------------------------------------------------------------------------------*/
字单元:存放一个字型数据(16位)的内存单元,由两个地址连续的内存单元组成。
高地址内存单元中存放字型数据的高位字节,低地址内存单元中存放字型数据的低位字节。
任何两个地址连续的内存单元,N号和N+1号单元,可以将它们看成两个内存单元,也可以看成一个地址为N的字单元中的高位字节单元和低位字节单元。
接下来说明DS和[address]的使用姿势:
mov ax,1000H
mov ds,bx
mov al,[0]
分析:mov指令的功能:1.将数据直接送入寄存器;
2.将一个寄存器中的内容送入另一个寄存器;
3.将一个内存单元中的内容送入另一个寄存器中。(内存单元在指令中必须指出)
mov al,[0]中[…]中的0代表内存单元的偏移地址。而8086CPU会自动取ds中的数据为内存单元的段地址。
因为8086CPU不能将数据直接送入段寄存器,而ds寄存器是一个段寄存器,所以需要用一个寄存器进行中转。即可用:mov ds,bx
也可以使用,mov 段寄存器,内存单元 如:
mov ax,1000H
mov ds,ax
mov ds,[0]
将10000H处存放的字型数据送入ds
将数据从寄存器送入到内存单元中是:mov 内存单元地址,寄存器名
将数据从内存单元送入到寄存器中是:mov 寄存器名,内存单元地址
栈:先进后出
8086CPU中提供了出栈和入栈的指令,最基本的两个是PUSH(入栈)和POP(出栈)
如:PUSH AX表示将寄存器ax中的数据送入栈中,POP AX表示从栈顶取出数据送入ax。它们都是以字为单位进行的。
可以进行以下操作:
mov ax,1000H
mov ds,ax
push [0]
pop [2]
这样的操作引出了一个问题:CPU如何知道栈顶的位置?
8086中有两个寄存器:段寄存器SS和寄存器SP
类似
4000
于CS和IP,SS中存放的是栈顶的段地址,偏移地址存放在SP中。同时,任意时刻有:SS:SP指向栈顶元素。
PUSH指令的执行步骤:1.SP=SP-2;
2.向SS:IP指向的内存单元中送入数据。
POP指令的执行步骤:1.从SS:SP指向的字单元中读取数据;
2.SP=SP-2。
SS:IP指向栈顶元素,当栈为空时,栈中没有元素,也就不存在栈顶元素,所以SS:IP只能指向栈的最底部单元下面的单元,该单元的地址为栈最底部的字单元的地址+2.
一个栈的最大容量为64KB.
debug的T命令在执行修改寄存器SS的指令时,下一条指令也紧接着被执行。
/*--------------------------------------------------------------------------分割线 有时间再更(看模电去了,难受)------------------------------------------------------------------------------------------------*/
内存地址空间的地址段分配如下:
1.地址0~7fffh的32kb空间为主随机存储器的地址空间;
2.地址8000~9fffh的8kb空间为显存地址空间;
3.地址a000h~ffffh的24kb空间为各个ROM的地址空间。
不要试图向ROM的地址空间内写入数据,因为,ROM怎么会这么轻易改变呢?
/*---------------------------------------------------------------------------------------------【BX】和loop指令-------------------------------------------------------------------------------------------------------------*/
inc 的含义是加1
loop指令的用法:CPU执行loop指令的时候,要进行两步操作:
1.(CX)=(CX)-1;
2.判断cx中的值,不为0则转至标号处执行程序,如果为0则向下执行。
通常用loop指令来实现循环功能,cx中存放循环次数。
例求2的12次方:
assume cs:code
code segment
mov ax,2
mov cx,11
s: add ax,ax
loop s
mov ax,4c00h
int 21h
code ends
end
程序猿们用汇编指令编写汇编源程序;汇编指令是机器指令的助记符。每一个CPU都有自己的汇编指令集。
指令和数据是应用上的概念。在内存或磁盘上,指令和数据没有任和区别,都是二进制信息。CPU在工作的时候,把有的信息看作指令,有的信息看作数据,为同样的信息赋予不同的意义。
CPU传输的电信号通过导线来传送。总线从物理上来讲,是一根根导线的集合。根据传送信息的不同,总线从逻辑上分为三类:地址总线,数据总线和控制总线。
地址总线:一个CPU有N根地址线,则可以说这个CPU的地址总线的宽度为N。这样的CPU最多可以寻找2的N次方个内存单元。(寻址能力)
8086的地址总线宽度为20,可以定位2^20个内存单元,则8086PC的内存地址空间大小为1MB,同理,80386CPU的地址总线宽度为32,则内存地址空间最大为4GB。
数据总线:8根数据总线一次可以传输一个字节,16根数据总线一次可以传输两个字节。8086CPU的数据总线宽度为16,8088CPU的数据总线宽度为8。(一次数据传送数量)
控制总线:CPU对外部器件的控制是通过控制总线来进行的。控制总线是个总称,控制总线是一些不同控制线的集合。有多少根控制总线,就意味着CPU提供了对外部器件的多少种控制。(控制能力)
/*--------------------------------------------------------------------------------------------分割线 寄存器------------------------------------------------------------------------------------------------------*/
8086CPU有14个寄存器,分别是:
AX,BX,CX,DX,SI,DI,SP,BP,IP,CS,SS,DS,ES,PSW.
这些寄存器都是16位的,可以放两个字节。
AX,BX,CX,DX用来存放一般性的数据,称为通用寄存器。为了兼容上代的CPU,这四个寄存器又都可以分为两个独立使用的8位寄存器:
AX:AH,AL; BX:BH,BL;CX:CH,CL;DX:DH,DL.
AX的低八位(0-7位)构成了AL寄存器,高八位(8-15位)构成了AH寄存器。AL产生的进位会丢失,而不会存储在AH中。
在写汇编指令或一个寄存器的名称时不区分大小写。
在进行数据传送或运算时,要注意指令的两个操作对象的位数应当是一致的。
8086是16位机:
1.运算器一次最多可以处理16位的数据;
2.寄存器的最大宽度为16位;
3.寄存器和运算器之间的通路为16位。
内存单元的地址在送上总线之前,必须在CPU中处理、传输、暂时存放,对于16位CPU,能一次处理、传输、暂时存储16位的地址。
因为8086有20位地址总线,如果将地址从内部简单的出发,那么它只能传送16位的地址。
8086CPU采用一种在内部用两个16位地址合成的方法来形成一个20位的物理地址。
物理地址=段地址*16+偏移地址
本质:CPU访问内存时,用一个基础地址(段地址*16)和一个相对于基础地址的偏移地址相加,给出内存单元的物理地址。
段地址*16必然是16的倍数,因此一个段的起始地址也一定是16的倍数;偏移地址为16位,16位地址的寻址能力为64KB,所以一个段的长度最大为64KB.(内存并没有分段,段的划分来自于CPU)
8086有4个段寄存器:CS,DS,ES,SS.
CS和IP寄存器指示了CPU当前要读取指令的地址。CS:代码段寄存器。IP:指令指针寄存器。
8086机中,任意时刻,CPU将CS:IP指向的内容当作指令执行。
8086的工作过程可简化如下:
1.从CS:IP指向的内存单元读取指令,读取的指令进入指令缓冲器;
2.IP=IP+所读取指令的长度,从而指向下一条指令;
3.执行指令。转到步骤1,重复这个过程。
在8086CPU加电位启动或复位后(即CPU刚开始工作时)CS和IP被设置为CS=FFFFH,IP=0000H,即在8086机刚启动时,CPU从内存FFFFH单元中读取指令执行,FFFF0H单元中的指令是8086机开机后执行的第一条指令。
指令和数据没有区别,那么CPU根据什么将内存中的信息看作指令?
CPU将CS:IP指向的内存单元中的内容看作指令。如果说,内存中的一段信息曾被CPU执行的话,那么它所在的内存单元必然被CS:IP指向过。
mov指令(传送指令),无法设置CS,IP的值。可通过jmp指令修改:
jmp 2AE3:3 执行后:CS=2AE3H,IP=0003H,CPU将从2AE33H处读取指令。
jmp 段地址:偏移地址
jmp 某一合法寄存器 可以仅修改IP的值,如:
jmp ax 执行指令前:ax=1000H,CS=2000H,IP=0003H
执行指令后:ax=1000H,CS=2000H,IP=1000H
/*--------------------------------------------------------------------------------分割线 寄存器(内存访问)----------------------------------------------------------------------------------------*/
字单元:存放一个字型数据(16位)的内存单元,由两个地址连续的内存单元组成。
高地址内存单元中存放字型数据的高位字节,低地址内存单元中存放字型数据的低位字节。
任何两个地址连续的内存单元,N号和N+1号单元,可以将它们看成两个内存单元,也可以看成一个地址为N的字单元中的高位字节单元和低位字节单元。
接下来说明DS和[address]的使用姿势:
mov ax,1000H
mov ds,bx
mov al,[0]
分析:mov指令的功能:1.将数据直接送入寄存器;
2.将一个寄存器中的内容送入另一个寄存器;
3.将一个内存单元中的内容送入另一个寄存器中。(内存单元在指令中必须指出)
mov al,[0]中[…]中的0代表内存单元的偏移地址。而8086CPU会自动取ds中的数据为内存单元的段地址。
因为8086CPU不能将数据直接送入段寄存器,而ds寄存器是一个段寄存器,所以需要用一个寄存器进行中转。即可用:mov ds,bx
也可以使用,mov 段寄存器,内存单元 如:
mov ax,1000H
mov ds,ax
mov ds,[0]
将10000H处存放的字型数据送入ds
将数据从寄存器送入到内存单元中是:mov 内存单元地址,寄存器名
将数据从内存单元送入到寄存器中是:mov 寄存器名,内存单元地址
栈:先进后出
8086CPU中提供了出栈和入栈的指令,最基本的两个是PUSH(入栈)和POP(出栈)
如:PUSH AX表示将寄存器ax中的数据送入栈中,POP AX表示从栈顶取出数据送入ax。它们都是以字为单位进行的。
可以进行以下操作:
mov ax,1000H
mov ds,ax
push [0]
pop [2]
这样的操作引出了一个问题:CPU如何知道栈顶的位置?
8086中有两个寄存器:段寄存器SS和寄存器SP
类似
4000
于CS和IP,SS中存放的是栈顶的段地址,偏移地址存放在SP中。同时,任意时刻有:SS:SP指向栈顶元素。
PUSH指令的执行步骤:1.SP=SP-2;
2.向SS:IP指向的内存单元中送入数据。
POP指令的执行步骤:1.从SS:SP指向的字单元中读取数据;
2.SP=SP-2。
SS:IP指向栈顶元素,当栈为空时,栈中没有元素,也就不存在栈顶元素,所以SS:IP只能指向栈的最底部单元下面的单元,该单元的地址为栈最底部的字单元的地址+2.
一个栈的最大容量为64KB.
debug的T命令在执行修改寄存器SS的指令时,下一条指令也紧接着被执行。
/*--------------------------------------------------------------------------分割线 有时间再更(看模电去了,难受)------------------------------------------------------------------------------------------------*/
内存地址空间的地址段分配如下:
1.地址0~7fffh的32kb空间为主随机存储器的地址空间;
2.地址8000~9fffh的8kb空间为显存地址空间;
3.地址a000h~ffffh的24kb空间为各个ROM的地址空间。
不要试图向ROM的地址空间内写入数据,因为,ROM怎么会这么轻易改变呢?
/*---------------------------------------------------------------------------------------------【BX】和loop指令-------------------------------------------------------------------------------------------------------------*/
inc 的含义是加1
loop指令的用法:CPU执行loop指令的时候,要进行两步操作:
1.(CX)=(CX)-1;
2.判断cx中的值,不为0则转至标号处执行程序,如果为0则向下执行。
通常用loop指令来实现循环功能,cx中存放循环次数。
例求2的12次方:
assume cs:code
code segment
mov ax,2
mov cx,11
s: add ax,ax
loop s
mov ax,4c00h
int 21h
code ends
end
相关文章推荐
- 王爽汇编语言学习笔记(四) --第一个程序
- 汇编语言学习笔记(五)
- 汇编语言学习笔记(5)——[bx]和loop
- 汇编语言学习笔记(2)
- 汇编语言学习笔记(三)寄存器(内存访问)
- 32位汇编语言学习笔记(37)--显示命令行参数
- 汇编语言学习笔记(随笔记) 端口
- 汇编语言学习笔记-按指定的字体输出文本
- 王爽汇编语言第二版学习笔记之实验13(1)
- 汇编语言第三章学习笔记和测试题
- 汇编语言-学习笔记(一)
- 汇编语言学习笔记(七)更灵活的定位内存地址的方法
- 32位汇编语言学习笔记(11)--条件传送指令
- 王爽汇编语言学习笔记(五)--loop与[bx]
- 32位汇编语言学习笔记(35)--显示ASCII表
- 汇编语言学习笔记(五)bx和loop指令
- 汇编语言学习笔记(可持续补充)
- 汇编语言学习笔记1.0-(基础知识、寄存器)
- IAR ARM中的汇编语言学习笔记
- 汇编语言学习笔记-接收键盘消息