数据处理与转移指令05
Posted lazyli
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据处理与转移指令05相关的知识,希望对你有一定的参考价值。
数据处理的两个基本问题
处理的数据在什么地方?
要处理的数据有多长?
定义,利用reg表示寄存器;sreg表示一个段寄存器
reg的集合包括:ax,bx,cx,dx,ah,al,bh,bl,ch,cl,dh,dl,sp,bp,si,di;
sreg的集合包括:ds,ss,cs,es;
1、在8086CPU中,只有4个寄存器可以[...]中来进行内存单元的寻址。
mov ax,[bx]
mov ax,[bx+si]
mov ax,[bx+di]
mov ax,[bp]
mov ax,[bp+si]
mov ax,[bp+di]
下面指令是错误的:
mov ax,[bx+bp]
mov ax,[si+di]
注:只要在[....]中使用寄存bp,而指令中没有显性地给出段地址,段地址就默认在ss中。
------------
2、机器指令处理的数据在什么地方
指令在执行前,所要处理的数据可以在3个地方,CPU内部、内存、端口;
mov bx,[0];在内存中
mov bx,ax ;在cpu内部,ax寄存器
mov bx,1; cpu内部,指令缓冲器
--------------
3、汇编语言中数据位置的表达
1)、立即数(idata)
对于直接包含在机器指令中的数据(执行前在CPU的指令缓冲器中);如:
mov ax,1
add bx,2000h
or bx,00100000b
mov al,‘a‘
2)、寄存器
指令要处理的数据在寄存器中,如:
mov ax,bx
mov ds,ax
push bx
mov ds:[0],bx
mov ss,ax
3)、段地址(SA)和偏移地址(EA)
指令要处理的数据在内存中
存放段地址的寄存器可以是默认的
mov ax,[0]
mov ax,[di]
mov ax,[bx+8]
----------------
4、寻址方式
直接寻址:[idata]
寄存器间接寻址:[bx]
寄存器相对寻址:[bx].idata;idata[si],[bx][idata]
基址变址寻址:[bx][si]
相对基址变址寻址:[bx].idata[si],idata[bx][si]
----------
5、指令要处理的数据有多长
8086CPU的指令,可以处理两种尺寸的数据,byte和word。
mov ax,1 ;字的操作,两个字节
mov al,1; 字节的操作,一个字节
利用 word ptr指明访问的内存单元时一个字
mov word ptr ds:[0]:1
利用byte ptr 指明了指令访问的内存单元时一个字节
mov byte ptr ds:[0],1
注:在没有寄存器参与的内存单元访问指令中,用word ptr和byte ptr显性地指明所要访问的内存单元长度是很有必要的。
mov ax,2000h
mov ds,ax
mov byte ptr [1000h],1
-----------
7、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存储除法操作的余数
格式如:
div reg
div 内存单元
div byte ptr ds:[0];表示除数是一个内存单元8位,那么被除数是在ax中,al存放商,ah存放余数
--------
8、伪指令dd
前面db是定义字节型数据
dw是定义字型数据
dd是定义双字型数据;两个字,这里的话也就是4个字节
db 1;占一个字节
dw 1;占一个字;2个字节
dd 1;占两个字;4个字节
----------
9、伪指令dup
dup是一个操作符,用来进行数据的重复;
db 3 dup(0)
定义了3个字节,它们的值都是0,相当于db 0,0,0;也就是dup(0),0是一个字节,重复3次;
db 3 dup(0,1,2);dup里面3个字节,重复3次,也就是0,1,2,0,1,2,0,1,2共9个字节
--------------
第九章
转移指令原理
可以修改IP,或同时修改cs和IP的指令统称为转移指令。转移指令就是可以控制CPU执行内存中某处代码的指令;
8086CPU的转移行为:
1、只修改IP时,称为段内转移,比如jmp ax。
2、同时修改cs和ip,称为段间转移,比如:jmp 1000:0
由于转移指令对IP的修改范围不同,段内转移又分为:短转移和近转移。
1、短转移IP的修改范围为-128至127
2、近转移IP的修改 范围为-32768至32767
8086CPU的转移指令分为:
1、无条件转移指令(如:jmp)
2、条件转移指令
3、循环指令(如:loop)
4、过程
5、中断
-------
1、操作符offset
offset在汇编语言中是由翻译器处理的符号,它的功能是取得标号的偏移地址。
assume cs:codesg
codesg segment
start: mov ax,offset start ;相当于mov ax,0
s: mov ax,offset s;相当于mov ax,3
codesg ends
end start
上面代码中,操作符offset取得了标号start和s偏移地址0和3。start是代码段中的标号,它所标记的指令是代码段中的第一条指令,偏移地址为0;
mov ax,offset s相当于指令mov ax,3,因为s是代码段的标号,它所标记的指令是代码段的第二条指令,第一条指令长度为3个字节,则s的偏移地址为3
--------------
2、jmp指令
jmp short 标号(短转移)
assume cs:codesg
codesg segment
start: mov ax,0
mov bx,0
jmp short s
add ax,1
s: inc ax
codesg ends
end start
注:jmp位移的范围是-128至127,向上128位字节,向下127字节;
jmp near ptr 标号:段内近转移,16位位移的范围为-32768至32767。
---------
4、转移的目的地址在指令中的jmp指令
前面讲的jmp指令,其对应的机器指令中并没有转移的目的的地址,而是相对于当前IP的转移位移。
"jmp far ptr 标号"实现的是段间转移,又称为远转移。
(CS)=标号所在段的段地址;(IP)=标号在段中的偏移地址。
far ptr指明了指令用标号的段地址和偏移地址修改CS和IP。
-----
5、转移地址在寄存器中的jmp指令
指令格式:jmp 16位reg
功能(IP)=(16位reg)
-----
6、转移地址在内存中的jmp指令
1)jmp word ptr 内存单元地址(段内转移)
mov ax,0123h
mov ds:[0],ax
jmp word ptr ds:[0]
2)jmp dword ptr内存单元地址(段间转移)
功能:从内存单元地址处开始存放着两个字,高地址处的字是转移的目的段地址,低地址处是转移的目的偏移地址。
(CS)=(内存单元地址+2)
(IP)=(内存单元地址)
mov ax,0123h
mov ds:[0],ax
mov word ptr ds:[2],0
jmp dword ptr ds:[0]
----------------
7、jcxz指令
jcxz指令为有条件转移指令,所有的条件转移指令都是短转移,在对应的机器码中包含转移的位移,而不是目的地址。对IP的修改范围都为:-128z至127
指令格式:jcxz标号(如果(cx)=0,转移到标号处执行。)
当(cx)!=0时,什么也不做,
”jcxz 标号"的功能相当于:if((cx)==0) jmp short 标号
mov cx,[bx]
jcxz ok
-----------
8、loop指令
loop指令为循环指令,所有的循环指令都是短转移,在对应的机器码中包含转移的位移,而不是目的地址。对IP的修改范围为:-128-127
"loop 标号"的功能相当于:
(cx)--;
if((cx)!=0) jmp short 标号;
----------
显存的空间:B8000H-BFFFFH共32KB的空间;向显存写入数据,那么就会在显示器上显示。
一个字符占两个字节,前面一个是ASCII码,后面一个是属性(颜色)【p190页】
------------
NOP"指令即空指令
运行该指令时单片机什么都不做,但是会占用一个指令的时间
当指令间需要有延时(给外部设备足够的响应时间;或是软件的延时等),可以插入“NOP”指令。
-----------------
第十章、CALL和RET指令
call和ret指令都是转移指令,它们都修改IP或同时修改CS和IP。
-------------
1、ret和retf
ret指令用栈中的数据,修改IP的内容,从而实现近转移;
retf指令用栈中的数据,修改CS和IP的内容,从而实现远转移;
CPU执行ret指令时,相当于:pop IP;将栈顶的值赋给IP
CPU执行retf指令时,相当于pop IP pop CS;
------
assume cs:code
stack segment
db 16 dup(0)
stack ends
code segment
mov,4c00h
int 21h
start: mov ax,stack
mov ss,ax
mov sp,16
mov ax,0
push ax
mov bx,0
ret
code ends
end start
上面程序,设置前两句是设置栈的段地址,将ax放入栈中,ret的命令是从栈顶中获取值(ax)=0赋予IP,这时的(IP)=0,下一条指令指向的是(IP)=0,指令的偏移地址为0,也是程序的第一条指令mov 4c00h,这是退出程序的指令
---------
assume cs:code
stack segment
db 16 dup(0)
stack ends
code segment
mov ax,4c00h
int 21h
start: mov ax,stack
mov ss,ax
mov sp,16
mov ax,0
push cs
push ax
mov bx,0
retf
code ends
end start
上面程序先设置栈的段地址、偏移地址;先将栈的段地址压入栈中,再将寄存器ax压入栈中,然后通过retf命令从栈中取出,先将寄存器ax(内容为0)从栈中取出,放入IP寄存器中,然后从栈中将cs取出放入寄存器CS中。这样下一条指令指向的段地址:偏移地址就是cs:ip;这里的(IP)=0
--------------
2、call指令
call指令经常跟ret指令配合使用,因此CPU执行call指令,进行两步操作
1、将当前的IP或CS和IP压入栈中
2、转移(jmp)
call指令不能实现短转移,
---
“call 标号":将当前的IP压入栈后,转到标号处执行指令;
功能:相当于执行标号,当执行完后可以从栈中取出call指令发出所在的IP地址,用作返回;比如说在一个方法中调用了另外一个方法,执行完方法后,返回继续执行当前方法剩下的程序。
call 标号:16位位移="标号"处的地址-call指令后第一个字节的地址
-------------
“call far ptr 标号"这种格式的call指令操作:
1)(sp)=(sp)-2
((ss)*16+(sp))=(cs)
(sp)=(sp)-2
((ss)*16+(sp))=(Ip)
先将原来的段地址:偏移地址保存到栈中
2)(cs)=标号所在的段地址
(ip)=标号所在的偏移地址
相当于:
push cs
push ip
jmp far ptr 标号
---------
call word ptr 内存单元地址
汇编语法解释
push IP
jmp word ptr 内存单元地址
--------
call与ret结合使用
assume cs:code
code segment
start: mov ax,1
mov cx,3
call
mov bx,ax
mov ax,4c00h
int 21h
s: add ax,ax
loop s
ret
code ends
end start
上面程序分析:当程序执行到call时,会将call下面一条指令的IP地址压入栈中,接着跳转到标号s程序处,执行循环操作,当(cx)=0跳出循环,ret指令将栈顶元素赋给寄存器IP,程序的指令会执行CS:IP处,这里就是mov bx,ax;(bx)=8,然后执行结束指令,结束程序;(p53要学习)
-----------
mul是乘法指令
1、两个相乘的数:要么都是8位,要么都是16位。如果是8位,一个默认放在AL中,另一个放在reg或内存字节单元中;如果是16位,一个默认在ax中,另一个放在16位reg或内存字单元中
2、结果:如果是8位乘法,结果默认放在ax中,如果是16位乘法,结果高位默认在dx中存放,低位在ax中放。
mul reg
mul 内存单元
mul byte ptr ds:[0] ;al中的值与内存字节单元的值相乘,存放在ax中。
mul word ptr [bx+si+8];ax中的值与内存字单元的值相乘,高位放在dx中,低位放在ax中
---------
dec指令是自减
div指令是除法;一般都在ax中进行,除的商放在ax中,余数放在dx中;如div cx;cx为除数,
字节操作:16位被除数在AX,8位除数为源操作数,结果的8位商在AL中,8位余数在AH中。
字操作:32位被除数放在DX,AX中。其中DX为高位字,16位除数为源操作数,结果的16位端在AX中,16位余数在DX中
双字操作:64位被除数在EDX,EAX中,其中EDX为高位双字,32位除数为源操作数,结果的32位商在EAX中,32位余数在EDX中
以上是关于数据处理与转移指令05的主要内容,如果未能解决你的问题,请参考以下文章