8086汇编-端口(14)
引言CPU可以直接读取3个地方的数据
1231.CPU内部的寄存器2.内存单元3.端口
1.端口的读写端口的读写不能用 mov
1.只能用in out
访问内存1234mov ax,ds:[8]1.CPU通过地址线将地址信息8发出2.CPU通过控制线发出内存读命令,选中存储器芯片,并通知它,将要从中读取数据存储器将8号单元中的数据通过数据线送入CPU
访问端口in是读,out是写
in al,60h
1从60H号端口读入一个字节
执行的时候操作
1231.CPU通过地址将地址信息60h发出2.CPU通过控制线发出端口读命令,选中端口所在的芯片,并通知它,将要从中读取数据3.端口所在的芯片将60h端口中的数据通过数据线送入CPU
2.注意
1在in 和 out 指令中,只能使用ax或al 来存从端口中读入的数据或要发送到端口中的数据。访问8位端口的时候,用al,访问16位端口的时候,用ax
3.对0~255以内的端口进行读写
12in al,20h ;从20h端口读入一个字节,放到al中out 20h,al ;往20h端口写入一个字节
4.对256~65535的端口进行读写 ...
8086汇编-int指令(13)
引言无
1.int 指令1.CPU指令int n 指令,相当于引发一个 n 号中断的中断过程,执行过程如下:
123451.取中断类型码 n ;2.标志寄存器入栈,IF=0 TF=03.CS,IP入栈4.(IP)=(N*4),(CS)=(N*4+2)从此转去执行n号中断的中断处理程序
2.int指令和call指令类似,但是int是调试中断指令,但是call是函数
2.编写供应用程序调用的中断例程
1231.编写实现平方功能的程序2.安装程序,我们将其安装在0:200中3.设置中断向量表,将程序的入口地址保存在7ch表项中,使其成为中断7ch的中断例程
123456789101112assume cs:code code segmentstart: mov ax,3456 ;(ax)=3456 int 7ch ;调用中断7ch的中断例程,计算ax中的数据的平方 add ax,ax adc dx,dx ;将结果乘以2 mov ax,4c00H int 21hcode endsend start
1234567891011121314151617181920212223242526 ...
8086汇编-内中断(12)
引言中断:外部终端和内部终端
1.中断处理程序1.CPU的设计者必须在中断信息和其处理程序的入口地址之间建立某种联系,使得COU根据中断信息可以找到要执行的处理程序
2.中断信息包含有标志中断源的类型码。根据CPU的设计,中断类型码的作用就是用来定位中断处理程序。
1比如CPU根据中断类型码4,就可以找到4号的处理程序
2.中断向量表1.CPU中8位的中断类型码,通过中断向量表找到相应的中断处理程序的入口地址
12起始就是一个索引一个类型码有一个对应的地址
2.中断向量表在内存中存放,对于8086CPU机,中断向量表指定放在内存地址0处
从内存0000:0000到0000:03ff的1024个内存单元中存放着中断向量表
123为什么是1024?1.一个地址是段地址和偏移地址组成【都是16位,也就是2个字节】所以一个地址就需要4个字节,一共是8位的中断类型码,也就是有256个中断类型码,所以需要1024个内存单元
3.中断过程1.8086CPU的中断过程
1234561.(从中断信息中)取得中断类型码2.标志寄存器的值入栈【PSW】--用于保护标志位3.设置标志寄存器的第8位TF和 ...
8086汇编-标志寄存器(11)
引言1.8086CPU的标志寄存器有16位,其中存储信息通常被称为程序状态字(PSW)
2.我们已经使用过8086CPU的ax,bx,cx,dx,si,di,bp,sp,ip,cs,ss,ds,es等13个寄存器
3.本章中的标志寄存器【flag】是我们的最后一个寄存器
4.flag和其他寄存器不一样,其他寄存器是用存放数据的,都是整个寄存器具有一个含义
5.而flag寄存器是安位起作用,也就是说:它的每一位都有专门的含义,记录特定的信息
6.flag在8086CPU中,只有 0 2 4 6 7 8 9 10 11具有特殊的含义,其他位置都没有意义
1.ZF标志1.flag的第6位是ZF,零标志位,它记录相关指令执行后
12结果为0, ZF=1结果不为0,ZF=0
2.比如
12345mov ax,1sub ax,1 执行后结果为0,则ZF=1mov ax,2sub ax,1 执行后结果为1,则ZF=0
3.对于ZF的值,我们可以这样来看,ZF标志相关指令的计算结果是否为0,如果是0,则在ZF要记录下“是0”这样的肯定信息
123mov ax,1add ax,0执行后,结果为0, ...
8086汇编-CALL和RET指令(10)
引言 1.程序之间的加载和返回
2.call和ret指令都是转移指令,它们大都修改IP,或者同时修改CS和IP
3.它们经常被同用来实现自程序的设计
1.ret和retf 指令1.ret指令是用栈中的数据,修改IP的内容,从而实现进转移
2.在CPU执行ret指令的时候
1234561.(IP)=((SS)*16+(SP))2.(sp)=(sp)+2IP中的值变成ss:[sp]中的sp+2【】pop ip
3.retf指令用栈中的数据,修改CS和IP的内容,从而实现远转移
4.在CPU执行retf指令的时候
123456789101.(IP)=((ss)*16+(sp))(sp)=(sp)+22.(cs)=((ss)*16+(sp))(sp)=(sp)+2低地址放的是ip,高地址放cs,都是字型单位pop ippop cs
2.call指令1.call指令经常和ret指令配合使用,因此CPU执行call指令
121.当前的IP或者CS和IP压入栈中2.转移(jmp)
2.call指令不能实现段转移,除此之外,call指令实现转移的方法和jmp指令的原理相同
3.依据位移进行转 ...
8086汇编-转移指令的原理(9)
引言1.8086CPU的转移指令分为以下几个类
123451.无条件转移指令【jmp】2.条件转移指令3.循环指令【loop】4.过程5.中断
1.操作符offset1.offset:伪指令,取得标号的偏移地址
1234assume cs:codesgcodesg segment start:mov ax,offset start ;相当于mov ax,0 就是取得start这个标号的偏移地址 s:mov ax,offset s ;相当于mov ax,3 也是去取得了s这个标号的偏移地址
小小的练习
填写指令,使改程序在运行中将s处的一条指令复制到s0处
123456789101112assume cs:codesgcodesg segment s: mov ax,bx ;mov ax,bx的机器码占2个字节 mov si,offset s mov di,offset s0 __________ __________ s0: nop nopcodesg endsend s
分析一下咯
123456789101.s和s0处的指令所在的内存地址是多少? cs:o ...
8086汇编-数据处理的俩个基本方法(8)
引言1.描述性符号
121.reg 来表示一个寄存器2.sreg 来表示一个段寄存器
1.bx,si,di,bp1.对 bx si di 进行一下小小的总结
123在8086CPU中,只有【bx,bp,si,di】可以用在[]中来进行内存单元的寻址[ax]这样是错的!!!!
2.在[]中,这4个寄存器可以单个出现,或者只能有4种组合
12345[bx+si];[bx+di][bp+si];[bp+di]si和di 不行bx和bp 不行
3.在[]内使用bp和bx的区别
12345如果是使用[bx]则默认段地址是ds ds是数据段地址如果使用[bp]则默认段地址是ss ss是栈段地址 所以这个bp和sp类似咯
2.机器指令处理的数据在什么地方1.绝大部分的机器指令都是进行数据处理的指令,处理大致可分为
1读取,写入,运算
2.在机器指令这一层来讲,并不关系数据的值是多少,而是关心指令执行前一刻,它将要处理的数据所在的位置
3.所要处理的数据可以在三个地方
1231.CPU内部2.内存3.端口
1234汇编指令 命令执行前数据的位置mov bx,[0] 内存, ds:0单元 ...
8086汇编-更灵活的定位内存地址的方法(7)
1.and 和 or 指令1.and指令:逻辑与指令,按位进行与运算 【一假即假】
123456按位与就是按位与咯01=0;10=0;11=1;00=0比如: mov al,01100011B and al,00111011B执行后 al=00100011B
功能:通过该指令可以将操作对象的相应位设置成0
12345比如: 将al中的第6位设为0 and al,10111111B 将第0位设为0 and al,11111110B
2.or指令:逻辑或,按位进行或运算【一真即真】
1234比如: mov al,01100011B or al,00111011B执行后: al=01111011B
功能:通过该指令可将操作对象的相应位设为1,其他位不变
123比如: al的第6位设置位1 or al,01000000B
2.关于ASCII码没什么…
3.以字符形式给处的数据1.在汇编中,我们可以用 ‘ xxx ‘ 的方式指明数据是以字符的形式给出的,编译器将把它们转化为相对应的ASCII码
比如:
1234567891011121314assume ds:data ...
8086汇编-包含多个段的程序(6)
1.在代码段中使用数据12345678910111213141516assume cs:codesgcodesg segment dw 0123H,0456H,0789H,0abcH,0defH,0fedH,0cbaH,0987H mov bx,0 mov ax,0 mov cx,8 s: add ax,cs:[bx] add bx,2 loop s mov ax,4c00H int 21h codesg endsend
1.dw的含义【dw 也是 define word】也就是定义字型数据
【每一个数据之前都需要用 , 隔开】
1同样可以衍生处db 【define byte】也就是定义字节型数据
问题1:这八个字型数据是放在哪里的呢?
123assume cs:codesgcodesg segment dw xxxxxx
123这8个数据肯定是放在这个定义好的cs【也就是代码段中】【所以他们的段地址肯定是cs】那这8个的偏移地址是多少呢?因为是在最开始的地方,所以偏移地址就是:2 4 6 8 ...
emmm,这8个字型数据放在了代码段,cpu就会 ...
8086汇编-[BX]和loop指令(5)
描述性符号“()”描述性符号()来表示一个寄存器或者一个内存单元中的!!内容!!
只能用来描述罢了
12345678910111213举个例子:1.ax中的内容是0010H则 (ax)=0010H2.2000:1000处的内容为0010H则 (21000H)=0010H3.对于mov ax,[2]的功能,我们可以这样来描述: (ax)=((ds)*16+2)4.对于push ax (sp)=(sp-2) ; 一定要注意是先改掉sp的位置在入栈 ((ss)*16+(sp))=(ax) ;这个就是把ax中的值入栈5.对于pop (ax)=((ss)*16+(sp)) (sp)=(sp)+2
约定符号idata表示常量123456789比如说 mov ax,[idata] 就代表 mov ax,[1] mov ax,[2] 在这里回顾一个知识点,段寄存器比如ds 不能使用 mov ds,[1] 所以在这里段寄存器就不能使用 mov ds,[idata] 因为段寄存器只能通过其他的寄存器来赋予 mov ds,[ax]
1.[bx][bx]和内存单元的描述1.[bx]是什么呢?
...