8086用于学习简单的原理(现在几乎都是x86
move和add指令:
汇编指令 行为 高级语言描述
mov ax,18 将18送入AX AX=18
mov ah,78 将78送入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
PS:汇编指令不区分大小写
PS:寄存器地位运算溢出时,溢出位不会影响到高位
物理地址
- CPU访问内存单元时要给出内存单元的地址
- 所有内存单元构成的存储空间是一个一维的线性空间
- 每一个内存单元在这个空间中都有唯一的地址,这个唯一的地址称为物理地址
- 物理地址=段地址x16+偏移地址
本质含义
- 用两个16位的地址(段地址,偏移地址),相加得到一个20位的物理地址
- CPU在访问内存的时候,用一个基础地址(段地址x16)和一个相对基础地址的偏移地址相加,给出内存单元的物理地址
用分段的方式管理内存
内存并没有分段,段的划分来自于CPU!!!
同一段内存,多种分段方案
假设起始地址(基础地址)为10000H和10080H,段地址为1000H和1008H,大小为80H
一个段最大长度为64K
同一个物理地址可以用不同的段地址和偏移地址
数据在21F60H内存单元中,段地址是2000H,说法:
(a)数据存在内存2000:1F60单元中;
(b)数据存在内存的2000H段中的1F60H单元中
段地址很重要!–用专门的寄存器存放段地址
4个段寄存器:
CS-代码段寄存器 DS-数据段寄存器
SS-栈段寄存器 ES-附加段寄存器
什么是debug?
debug是DOS,Windows都提供的实模式(8086方式)程序的调试工具.使用它可以查看CPU各种寄存器的内容,内容的情况和在机器码级跟踪程序的运行
我们用到的debug功能
1. R命令:查看,改变CPU寄存器的内容
2. D命令:查看内存中的内容
d #列出预设地址内存处的128个字节的内容
d 段地址:偏移地址 #列出内存中指定地址处的内容
d 段地址:偏移地址 结尾偏移地址 #列出内存中指定地址范围内的内容
3. E命令:改写内存中的内存
e 段地址:偏移地址 数据1 数据2 ... #从该地址开始写数据
e 段地址:偏移地址
逐个询问式修改
空格 # 接受,继续
回车 # 结束
4. U命令:将内存中的机器指令翻译成汇编指令
汇编指令
mov ax,0123H
mov bx,0003H
mov ax,bx
add ax,bx
对应的机器码
B8 23 01
BB 03 00
89 D8
01 D8
e 地址 数据 #写入
d 地址 #查看
u 地址 查看代码
5. T命令:执行一条机器命令
t #执行CS:IP处的指令
6. A命令:以汇编指令的格式在内存中写入一条机器指令
a 地址 #写入汇编指令
d 地址 #查看数据
u 地址 # 查看代码
7. Q命令:退出debug
两个关键的寄存器
CS:代码段寄存器
IP:指令指针寄存器
CS:IP :CPU将内存中CS:IP指向的内容当作指令执行
8086PC工作过程的简要描述:
(1)从CS:IP指向内存单位读取指令,读取的指令进入指令缓存器;
(2)IP=IP+所读的指令的长度,从而指向下一条命令
(3)执行指令,转到步骤(1)
修改CS,IP的指令:
转移指令:jmp同时修改CS,IP的内容: jmp 段地址:偏移地址
仅修改IP的内容:jmp ax (类似于mov IP,ax)
内存中字的存储
事实:对8086CPU,16位作为一个字
16位的字在内存中需要2个连续字节存储,怎么存放?
低位字节存在低位地址单元高位字节存在高位地址单元
例:20000D(4B20H)存放在1,0两个单元,18D(0012H)存放在2,3两个单元
20H 4EH 12H 00H 0->
CPU要读取一个内存单元的时候,必须先给出这个内存单元的地址;
用DS寄存器放要访问的数据的段地址
偏移地址用[…]形式直接给出
用mov指令操作数据:(add加法,sub减法类似)
指令形式 例示
mov寄存器,数据 mov ax,8
mov寄存器,寄存器 mov ax,bx
mov寄存器,内存单元 mov ax,[0]
mov内存单元,寄存器 mov[0],ax
mov段寄存器,寄存器 mov ds,ax
大胆地假设,小心地求证 –胡适
栈结构:
栈是一种只能在一端进行插入或删除操作的数据结构.
入栈:将一个新的元素放到栈顶;
出栈:从栈顶取出一个元素
8086中栈的指令:
push入栈和pop出栈
push ax:将ax中的数据送入栈中
pop ax:从栈顶取出数据送入ax(以字为单位对栈进行操作)
在8086中有两个与栈相关的寄存器:
栈段寄存器SS 存放栈顶的段地址
栈顶指针寄存器SP 存放栈顶的偏移地址
任意时刻,SS:SP指向栈顶元素
编程时,可以根据需要将一组内存单元定义一个段
可以将起始地址为16的倍数,长度N(N<64K)的一组地址连续的内存单元,定义为一个段.
数据段:DS
代码段:CS:IP
栈段:SS:SP
程序中的三种指令
assume cs:codesg
codesg segment
mov ax,0123H
mov bx,0456H
add ax,bx
add ax,ax
mov ax,4c00h
int 21h
codesg ends
end
段定义:
一个汇编程序是由多个段组成的,这些段被用来存放代码,数据,或当作栈空间来使用
一个有意义的汇编程序中至少要有一个段,这个段用来存放代码
定义程序中的段:每个段都需要有段名
段名 segment –段的开始
段名 ends –段的结束
end(不是ends):
汇编程序的结束标记,若程序结尾处不加end,编译器在编译时无法知道在何处结束
assume(假设):
假设某一字段寄存器和程序中的某一个用segment..ends定义的段相关联; 注释
.asm->masm命令->.obj->link->.exe
再约定:符号idata表示常量
loop和[bx]联手读取连续的内存:
这个程序还是有问题的
在代码段中使用栈:i数据逆序存放 栈需要内存空间,在程序中通过,定义’空’数据来取得.
处理字符问题: 汇编程序中,用’……’的方式指明数据是以字符的形式给出的,编译器将他们转化为相对应的ASCII码
[bx+idata]的寻址方式:
[bx+idata]表示一个内存单元,他的偏移地址为(bx)+idata(bx中的数值加上idata). mov ax,[bx+200]/mov ax,[200+bx]的含义 将一个内存单元的内容送入ax 这个内存单元的长度为2字节(字单元),存放一个字 内存单元的段地址在ds中,偏移地址为200加上bx中的数值 指令mov ax,[bx+200]的其他写法(常用) mov ax,[200+bx] mov ax,200[bx] mov ax,[bx].200
SI和DI寄存器:
目前所学的寻址方式:
8086CPU有14个寄存器:
通用寄存器:AX,BX,CX,DX
变址寄存器:SI,DI
指针寄存器:SP,BP
指令指针寄存器:IP
段寄存器:SCS,SS,DS,ES
标志寄存器:PSW
在哪里?有多长?
div除法指令
dup的功能和用法
转移综述
用操作符offset取得标号的偏移地址
jmp指令
call指令和ret指令
标识寄存器
带进位的加减法
cmp和条件转移指令
DF标志和串传送指令
位移指令
操作显存数据
描述内存单元的标号
数据的直接定址表
直接定址表:利用表,再两个数据集合之间建立一种映射关系,用查表的方式根据给出的数据,得到其在另一一个集合中的数据.
优点:算法清晰和简介,加快运算速度,使程序易于扩充
暂无评论内容