mov word ptr x,ax,什么意思
将16位寄存器AX中的数据,复制传送到变量X所指向的两个字节16位存储单元中。
本来,若变量X定义成了16位的字类型变量(即用DW定义),可以直接写 MOV X, AX
但因为X未定义成字,可能是用DB定义成了8位的字节,也可能是用DD定义成了32位的双字,直接那样写会出现两个操作数类型不一致的错误。所以就加上WORD PTR指定这一次将X变量地址当成字类型变量使用。
MOV 是数据传送指令。
前面一个操作数 WORD PTR X是目的操作数,也就是说数据住这儿存放。其中,X是变量名。
后面的AX是通用寄存器中的16位累加器。
bx,si,di和bp
只有bx,si,di和bp四个寄存器可以用在[…]中来进行内存单元的寻址。
√ mov ax,[bx+si]
× mov ax,[cx]
在[…]中这四个寄存器可单个出现,或只能以四种组合出现
- bx 和 si
- bx 和 di
- bp 和 si
- bp 和 di
在[…]中使用bp,未显性给出段地址,默认为ss
汇编寄存器中 ax 和[ax] 什么区别
对AX进行操作时操作的是AX寄存器里面的值 对[AX]进行操作的时候 是将AX寄存器里面的值当做偏移地址 对DS:[AX]这个内存单元里面的值进行操作
汇编语言数据位置表达
- 立即数(idata)
eg: mov ax,1 ; or bx,00010000b - 寄存器
eg: mov ax,bx ; - 段地址(SA)和偏移地址(EA)
eg: mov ax,[bx+si+8]
指明指令处理的数据长度
- 寄存器名:
ax al - 操作符 word(byte) ptr
mov word ptr ds:[0],1
mov byte ptr ds:[0],1 - 其他方法
push [1000h] push指令只进行字操作
汇编inc用法
加1指令 INC
指令功能 目标操作数+1
伪指令db,dw,dd
db (b:byte) 定义字节型数据
dw (w:word) 定义字型数据
dd (d:double word) 定义双字型数据
dup
一个操作符,和数据定义伪指令配合使用,进行数据的重复
db 3 dup (0) 定义了三个字节,都是0
db 3 dup(0,1,2)定义了9个字节,是0,1,2,0,1,2,0,1,2
div指令
div是除法指令
(1)除数:有8位和16位两种,在一个reg或内存单元中
(2)被除数:默认放在AX 或 AX和DX中
除数 | 被除数 | 被除数存放 |
---|---|---|
8位 | 16位 | AX |
16位 | 32位 | DX(高16位)和AX(低16位) |
(3)结果:
除数 | 存储 |
---|---|
8位 | AL(存储商)AH(存储余数) |
16位 | AX(存储商)DX(存储余数) |
格式:
div reg
div 内存单元
操作符offset
由编译器处理,作用:取得标号的偏移地址
start: mov ax,offset start ;相当于mov ax,0 (start偏移地址为0)
jmp指令
一、依据位移进行转移
jmp short 标号(转到标号处执行指令)
实现段内短转移,对ip的修改范围为-128~127
转移指令结束后,CS:IP应指向标号处的指令
CPU在执行jmp指令时并不需要转移的目的地址,告诉了CPU要转移的位移
jmp near ptr 标号
实现段内近转移
功能:(IP)=(IP)+16位位移
二、转移的目的地址在指令中的jmp指令
jmp far ptr 标号实现的是段间转移,又称远转移
start: mov ax,0
mov bx,0
jmp far ptr s ;编译后机器码EA0B01BD0B,包含转移的目的地址
db 256 dup(0)
s: add ax,1
三、转移地址在寄存器中的jmp指令
格式:jmp 16位reg
功能:(IP)=(16位reg)
mov指令不能设置CS、IP的值
能够改变CS、IP的指令称为转移指令(如jmp)
[格式] jmp 段地址:偏移地址(修改CS、IP值)
jmp 2AE3:3,执行后:CS=2AE3H,IP=0003H
[格式] jmp 某一合法寄存器 (修改IP的内容)
jmp ax,含义上好似 mov IP,ax
四、转移地址在内存中的jmp指令
- jmp word ptr 内存单元地址(段内转移)
执行后(IP)=0123Hmov ax,0123H mov ds:[0],ax jmp word ptr ds:[0]
- jmp dword ptr 内存单元地址(段间转移)
功能:内存单元地址处开始存放着两个字,高地址:转移的目的段地址,低地址:转移的目的偏移地址
执行后,(CS)=0,(IP)=0123H,CS:IP指向0000:0123mov ax,0123h mov ds:[0],ax mov word ptr ds:[2],0 jmp dword ptr ds:[0]
jcxz指令
jcxz 标号
如果cx=0,转移到标号处执行
loop指令
循环指令,所有循环指令都是短转移
格式 loop 标号
(cx)=(cx)-1,如果(cx)≠0,转移到标号处执行
call 和ret指令
1.ret和retf
ret | 用栈中的数据,修改IP的内容 | 近转移 |
---|---|---|
retf | 用占中的数据,修改CS和IP的内容 | 远转移 |
ret指令,CPU进行:
(1) (IP)=((SS16)+(SP))
(2) (SP)=(SP)+2
retf指令,CPU进行:
(1) (IP)=((SS16)+(SP))
(2) (SP)=(SP)+2
(3) (CS)=((SS*16)+(SP))
(4) (SP)=(SP)+2
2.call指令
(1)将当前IP/(CS&IP)压入栈中
(2)转移
2.1依据位移进行转移的call指令
call 标号
将当前IP压栈后,转到标号处执行指令
2.2转移的目的地址在指令中的call指令
call far ptr 标号
实现的是段间转移
CPU进行:
(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 标号
2.3转移地址在寄存器的call指令
格式: call 16位reg
相当于
push IP
jmp 16位reg
mul指令
乘法指令
- 两个相乘的数:
都是8位 一个默认在AL,另一个在8位reg/内存 都是16位 一个默认在AX,另一个在16位reg/内存 - 结果
8位 结果默认在AX 16位 结果高位在DX,低位在AX
格式:
mul reg
mul 内存单元
汇编语言的ADC和ADD怎么理解
ADD是普通的加法指令,ADC是带进位的加法指令。
两者的格式都为:
ADD/ADC source,destination
将源操作数的值与目标操作数的值相加,并将运算结果放在目标操作数指示的位置。并根据相加结果设置标志寄存器的CF,PF,AF,ZF,SF,OF。
唯一的不同是,ADC执行加法运算时,会将CF位的值一起加到目标操作数中。所以ADC常用于处理以下情况:
如果必须处理非常大的、不能存放到双字数据长度(ADD可以使用的最大长度)中的整数,可以把值分割为多个双字数据元素,并且对每个元素执行独立的加法操作。
为了正确完成这个操作,必须检测每个加法操作的进位标志,如果进位标志被设置为1,就必须进位到下一对相加的数据元素。
ADC指令执行两个无符号或者带符号整数值的加法,并且把前一个ADD指令产生的进位标志的值包含在其中。ADC指令也按照操作结果正确地设置进位和溢出标志。
SUB 是常规的减法
SBB 是带借位的减法
标志位简介:
标志寄存器,又称程序状态寄存器(它的内容是Program Status Word,PSW).这是一个存放条件码标志,控制标志和系统标志的寄存器
6个状态标志位
CF—进位标志,加法时的最高位(D7或D15)产生进位或减法时最高位出现借位,则CF=1,否则CF=0;
AF—辅助进位标志,供BCD码使用。当D3位出现进位或借位时AF=1,否则AF=0;
OF—溢出标志,带符号数进行算术运算时,其结果超出了8位或16位的表示范围,产生溢出, 则OF=1,否则OF=0;
ZF—零标志,运算结果各位都为零,则ZF=1,否则ZF=0;
SF—符号标志,运算结果为负数时,即运算结果的最高位为1,则SF=1,否则SF=0;
PF—奇偶标志,反映操作结果中“1”的个数的情况,若有偶数个“1”,则PF=1,否则PF=0。
3个控制标志位
DF—方向标志,用来控制数据串操作指令的步进方向;
当设置DF=1时,将以递减顺序对数据串中的数据进行处理。当设置DF=0时,递增。
IF—中断允许标志,当设置IF=1,开中断,CPU可响应可屏蔽中断请求;当设置IF=0时,关中断,CPU不响应可屏蔽中断请求。
TF—陷阱标志,为程序调试而设的。当设置TF=1,CPU处于单步执行指令的方式;当设置TF=0时,CPU正常执行程序。
详解:
1、进位标志CF (Carry Flag)
当运算结果的最高有效位有进位(加法)或借位(减法)时,进位标志置1,
即CF = 1;否则CF = 0。49H + 6DH=B6H,
没有进位:CF = 0BBH + 6AH=(1)25H,有进位:CF = 1
2、零标志ZF (Zero Flag)
若运算结果为0,则ZF = 1;
否则ZF = 049H + 6DH=B6H,结果不是零:
ZF = 075H + 8BH=(1)00H,结果是零:ZF = 1
3、符号标志SF (Sign Flag)
运算结果最高位为1,则SF = 1;
否则SF = 049H + 6DH=B6H,
4、奇偶标志PF(Parity Flag)
当运算结果最低字节中“1”的个数为零或偶数时,PF = 1;
否则PF = 03AH + 7CH=B6H=10110110B结果中有5个1,是奇数:PF = 0
5、溢出标志OF (Overflow Flag)
若算术运算的结果有溢出,则OF=1;
否则 OF=049H + 6DH =B6H,产生溢出:OF = 175H + 8BH =(1)26H,
没有溢出:OF = 0
什么是溢出?
处理器内部以补码表示有符号数8位表达的整数范围是:+127~-12816位
表达的范围是:+32767~-32768
如果运算结果超出这个范围,就产生了溢出有溢出,说明有符号数的运算结果不正确49H+6DH=B6H,就是73+109=182,已经超出-128~+127范围,产生溢出,故OF=1;
另一方面,补码B6H表达真值是-74,显然运算结果也不正确
溢出标志OF和进位标志CF是两个意义不同的标志
进位标志表示无符号数运算结果是否超出范围,运算结果仍然正确;
溢出标志表示有符号数运算结果是否超出范围,运算结果已经不正确。
例1:49H + 6DH=B6H无符号数运算:
73+109=182范围内,
无进位有符号数运算:73+109=182范围外,有溢出
例2:BBH + 6AH=(1)25H无符号数运算:
187+106=293范围外,
有进位有符号数运算:-69+106=37范围内,无溢出
溢出的判断判断运算结果是否溢出有一个简单的规则:只有当两个相同符号数相加(包括不同符号数相减),而运算结果的符号与原数据符号相反时,产生溢出;因为,此时的运算结果显然不正确其他情况下,则不会产生溢出
6、辅助进位标志AF(Auxiliary Flag)
运算时D3位(低半字节)有进位或借位时,AF = 1;
否则AF = 0。49H + 6DH=B6H,D3有进位:AF = 1
7、方向标志DF(Direction Flag)
用于串操作指令中,控制地址的变化方向:设置DF=0,存储器地址自动增加;
设置DF=1,存储器地址自动减少。
CLD指令复位方向标志:DF=0STD指令置位方向标志:DF=1
8、中断允许标志IF(Interrupt Flag)
用于控制外部可屏蔽中断是否可以被处理器响应:
设置IF=1,则允许中断;
设置IF=0,则禁止中断。
CLI指令复位中断标志:IF=0
STI指令置位中断标志:IF=1
9、陷阱标志TF(Trap Flag)
用于控制处理器进入单步操作方式:
设置TF=0,处理器正常工作;
设置TF=1,处理器单步执行指令。
单步执行指令——处理器在每条指令执行结束时,便产生一个编号为1的内部中断这种内部中断称为单步中断所以TF也称为单步标志利用单步中断可对程序进行逐条指令的调试这种逐条指令调试程序的方法就是单步调试
EU控制器是执行指令的控制电路,实现从队列中取指令、译码、产生控制信号等。,
在(cmd debug)调试程序中为了使标志位的值显尔易见,他提供用符号表示标志位的值。
标志 | 值为1的标记 | 值为0的标记 |
---|---|---|
of | OV | NV |
df | DN | UP |
if | EI | DI |
sf | NG | PL |
zf | ZR | NZ |
af | AC | NA |
pf | PE | PO |
cf | CY | NC |
cmp指令
cmp ax,bx
如果(ax)=(bx), 则 zf=1
如果(ax)!=(bx), 则 zf=0
如果(ax)<(bx), 则 cf=1
如果(ax)>=(bx), 则 cf=0
如果(ax)>(bx), 则 cf=0且zf=0
如果(ax)<=(bx), 则 cf=1或zf=1
cmp指令配合和条件转移指令配合使用
条件转移指令
指令 | 含义 | 检测的相关标志位 |
---|---|---|
je | 等于则转移 | zf=1 |
jne | 不等于则转移 | zf=0 |
jb | 低于则转移 | cf=1 |
jnb | 不低于则转移 | cf=0 |
ja | 高于则转移 | cf=0且zf=0 |
jna | 不高于则转移 | cf=1或zf=1 |
DF标志和串传送指令
DF 方向标志位,在串处理指令中,控制每次操作后si、di的增减
df=0 每次操作后si、di递增
df=1 每次操作后si、di递减
movsb:
相当于
mov es:[di],byte ptr ds:[si]
如果 df=0
inc di
inc si
如果 df=1
dec di
dec si
movsw:
相当于
mov es:[di],word ptr ds:[si]
如果 df=0
add si,2
add di,2
如果 df=1
sub si,2
sub di,2
一般来说,movsb和movsw都和rep配合使用,格式如下:
rep movsb
或者
rep movsw
相当于
s:movsb
loop s
为什么有的立即数前面要加0?
8086/8088的汇编语言里面,以字母开头的16进制数,前面必须加“0”。如0a2h,0fdh,0bcdeh等。
汇编语言中,出栈后 出栈的那个数值在栈中会被清零吗?
汇编语言中,出栈后 出栈的那个数值在栈中 不会 被清零,
但是 如果有 新的 压栈操作(入栈),会被新的数据替代。