一、实验目的
1. 学习算术与逻辑运算的原理及指令的用法; 2. 进一步学习emu8086调试程序的用法,并学会emu8086下编写简单应用程序的方法;
3. 掌握BCD码加、减法以及ASCII码加减法。
二、实验内容
1. 用emu8086执行各加减法指令以及不同编码方式的运算方法,记录执行结果,进行分析、比较,掌握各功能类似的指令之间的差别。
2. 用emu8086编写一个COM文件,其功能是检查自身的长度以及代码检查和。如果自身的长度改变或检查和改变,则显示“VIRUS”,否则显示“OK”。
三、实验步骤
(一) 加法、减法以及逻辑运算指令练习 1. 启动emu8086;
2. 用单步按钮命令调试以下程序段(分号后注释部分不用输入);
-A
xxxx:0100 XOR AX,AX
;AX= , C=____, Z=____
xxxx:0102 MOV AX,89AB ;AX= , C=____, Z=____ xxxx:0105 MOV BX,AX xxxx:0107 INC AX xxxx:0108 DEC AX
;BX=
;AX= , C=____, Z=____ ;AX= , C=____, Z=____
;AX= , C=____, Z=____ ;AX= , C=____, Z=____ ;AX= , C=____, Z=____ ;AX= , C=____, Z=____
xxxx:0109 ADD AX,SI xxxx:010B SUB AX,SI xxxx:010D ADC AX,SI xxxx:010F SBB AX,SI xxxx:0111 NOP
xxxx:0112 MOV AX,0808 xxxx:0115 MOV BX,0080
xxxx:0118 MOV CX,0880 ;CX=___________
xxxx:011B OR AX,BX ;AX=___________ , C=____, OV=____ xxxx:011D MOV AX,0808 ;AX=___________, BX=___________
xxxx:0120 AND AX,CX ;AX=___________, C=____, S=____ xxxx:0122 MOV AX,0808 ;AX=___________, CX=___________ xxxx:0125 XOR AX,BX ;AX=___________, BX=___________ xxxx:0127 NOT AX ;AX=___________ xxxx:0129 NEG AX ;AX=___________ xxxx:012B
3. 分析上述程序段,用铅笔填写指令依次执行后寄存器和标志位的值,观察它们的变化。
4.给SI寄存器赋值:
SI 0000修改7777
5. 单步执行以上程序段,依次与你的分析结果核对,如有错,则纠正自己理解上的偏差,加深认识,并将正确结果填入空格内。 6. 保存该程序并退出emu8086 (二) 十进制(BCD码)加减法练习
1.;emu8086
2. 按如下顺序进行操作,记录结果并分析原因; -a100
xxxx:0100 XOR AL,AL xxxx:0102 INC AL xxxx:0104 DAA
xxxx:0105 JMP 102
用交换指令实现寄存器之间的数据交换 mov ax,1234h ;ax=1234h mov bx,5678h ;bx=5678h
xchg ax,bx ;ax=5678h,bx=1234h
xchg ah,al ;ax=7856h
用交换指令实现寄存器与存储器之间的数据交换 xchg ax,[2000h] ;也可以表达为xchg [2000h],ax xchg al,[2000h] ;也可以表达为xchg [2000h],al 将7812h压入堆栈
mov ax,7812h
push ax
将主存单元DS : [2000H]的一个字压入堆栈 push [2000h]
例2.10a:将栈顶一个字的内容弹出送AX寄存器
pop ax
例2.10b:将栈顶一个字送入主存DS : [2000H] pop [2000h] 标志寄存器传送
LAHF ;AH←FLAGS的低字节
SAHF ;FLAGS的低字节←AH
SAHF和LAHF是一对相反功能的指令。它们只影响标志寄存器的低8位。
PUSHF ;SP←SP-2,SS:[SP]←FLAGS POPF ;FLAGS←SS:[SP],SP←SP+2
PUSHF指令可用来保存全部标志位,POPF指令设置标志寄存器。 2.12:置位单步标志TF
pushf ;保存全部标志到堆栈 pop ax ;从堆栈中取出全部标志
or ax,0100h ;设置D8=TF=1,而ax其他位不变 push ax ;将ax压入堆栈
popf ;将堆栈内容取到标志寄存器:即FLAGS←AX 标志位操作
CLC ;复位进位标志:CF←0 STC ;置位进位标志:CF←1
CMC ;求反进位标志:CF← ~CF
CLD ;复位方向标志:DF←0 STD ;置位方向标志:DF←1
CLI ;复位中断标志,禁止可屏蔽中断:IF←0 STI ;置位中断标志,允许可屏蔽中断:IF←1 例2.13:有效地址的获取
mov bx,0400h mov si,3ch
lea bx,[bx+si+0f62h] ;BX=139EH 例2.14:地址指针的传送
mov word ptr[3060h],0100h mov word ptr[3062h],1450h
lds si,[3060h] ;ds=1450h,si=0100h les di,[3060h] ;es=1450h,di=0100h
例2.15a:用字节输入指令从20h和21h端口输入一个字数据 in al,21h mov ah,al
in al,20h
2.15b:用字输入指令从20h和21h端口输入一个字数据 in ax,20h
2.15c:用DX间接寻址从20h和21h端口输入一个字数据 mov dx,20h in ax,dx
2.16:将数据80h送到3fch端口 mov dx,3fch mov al,80h out dx,al 例2.17a:加法运算
mov al,0fbh ;al=0fbh
add al,07h ;al=02h
mov word ptr[200h],4652h ;[200h]=4652h mov bx,1feh ;bx=1feh add al,bl ;al=00h
add word ptr[bx+2],0f0f0h ;[200h]=3742h
例2.17b:无符号双字加法运算(带进位加法指令ADC) mov ax,4652h ;ax=4652h
add ax,0f0f0h ;ax=3742h,CF=1 mov dx,0234h ;dx=0234h
adc dx,0f0f0h ;dx=f325h,CF=0
SUB reg,imm/reg/mem ;reg←reg-imm/reg/mem SUB mem,imm/reg ;mem←mem-imm/reg
例2.18a:减法运算
mov al, 0fbh ;al=0fbh
sub al, 07h ;al=0f4h,CF=0
mov word ptr [200h],4652h ;[200h]=4652h mov bx,1feh ;bx=1feh sub al,bl ;al=0f6h,CF=1
sub word ptr [bx+2],0f0f0h ;[200h]=5562h,CF=1 例2.18b:无符号双字减法运算(带借位减法指令SBB)
mov ax,4652h ;ax=4652h
sub ax,0f0f0h ;ax=5562h,OF=0、SF=0、ZF=0、AF=0、PF=0、CF=1 mov dx,0234h ;dx=0234h
sbb dx,0f0f0h ;dx=1143h,OF=0、SF=0、ZF=0、AF=0、PF=0、CF=1 dec cx inc ax 例2.19:求补运算
mov ax,0ff64h
neg al ;ax=ff9ch,OF=0、SF=1、ZF=0、PF=1、CF=1 sub al,9dh ;ax=ffffh,OF=0、SF=1、ZF=0、PF=1、CF=1 neg ax ;ax=0001h,OF=0、SF=0、ZF=0、PF=0、CF=1 dec al ;ax=0000h,OF=0、SF=0、ZF=1、PF=1、CF=1 neg ax ;ax=0000h,OF=0、SF=0、ZF=1、PF=1、CF=0 例2.20:比较AL是否大于100 cmp al ,100 ;al-100
jb below ;al<100,跳转到below执行 sub al,100 ;al≥100,al←al-100 inc ah ;ah←ah+1
below: ...
例2.21a:无符号数0B4H与11H相乘
mov al,0b4h ;al=b4h=180d
mov bl,11h ;bl=11h=17d
mul bl ;ax=Obf4h=3060d,OF=CF=1(AX高8位不为0) 例2.21b:有符号数0B4H与11H相乘(有符号数乘法指令IMUL) mov al,0b4h ;al=b4h=-76d
mov bl,11h ;bl=11h=17d
imul bl ;ax=faf4h=-1292d,OF=CF=1
;AX高8位不是低8位的符号扩展,表示含有有效数字 例2.22a:无符号数0400H除以B4H mov ax,0400h ;ax=400h=1024d mov bl,0b4h ;bl=b4h=180d
div bl ;商al=05h,余数ah=7ch=124d 例2.22b:有符号数0400H除以B4H
mov ax,0400h ;ax=400h=1024d
mov bl,0b4h ;bl=b4h=-76d
idiv bl ;商al=f3h=-13d,余数ah=24h=36d 例2.23:符号扩展
mov al,80h ;al=80h cbw ;ax=ff80h add al,255 ;al=7fh cbw ;ax=007fh
例2.24:进行有符号数除法AX÷BX
cwd idiv bx
例2.25a:压缩BCD码的加法运算
mov al,68h ;al=68h,表示压缩BCD码68 mov bl,28h ;bl=28h,表示压缩BCD码28 add al,bl ;二进制加法:al=68h+28h=90h daa ;十进制调整:al=96h
;实现压缩BCD码加法:68+28=96 例2.25b:压缩BCD码的减法运算
mov al,68h ;al=68h,表示压缩BCD码68 mov bl,28h ;bl=28h,表示压缩BCD码28 sub al,bl ;二进制减法:al=68h-28h=40h das ;十进制调整:al=40h
;实现压缩BCD码减法:68-28=40
例2.27a:非压缩BCD码的加法运算
mov ax,0608h ;ax=0608h,表示非压缩BCD码68 mov bl,09h ;bl=09h,表示非压缩BCD码9 add al,bl ;二进制加法:al=08h+09h=11h aaa ;十进制调整:ax=0707h
;实现非压缩BCD码加法:68+9=77 例2.27b:非压缩BCD码的减法运算
mov ax,0608h ;ax=0608h,表示非压缩BCD码68 mov bl,09h ;bl=09h,表示非压缩BCD码9 sub al,bl ;二进制减法:al=08h-09h=ffh aas ;十进制调整:ax=0509h
;实现非压缩BCD码减法:68-9=59 例2.27b:非压缩BCD码的减法运算
mov ax,0608h ;ax=0608h,表示非压缩BCD码68 mov bl,09h ;bl=09h,表示非压缩BCD码9 sub al,bl ;二进制减法:al=08h-09h=ffh aas ;十进制调整:ax=0509h
;实现非压缩BCD码减法:68-9=59 例2.27c:非压缩BCD码的乘法运算
mov ax,0608h ;ax=0608h,表示非压缩BCD码68 mov bl,09h ;bl=09h,表示非压缩BCD码9 mul bl ;二进制乘法:ax=08h×09h=0048h aam ;十进制调整:ax=0702h
;实现非压缩BCD码乘法:8×9=72 例2.27d:非压缩BCD码的除法运算
mov ax,0608h ;ax=0608h,表示非压缩BCD码68 mov bl,09h ;bl=09h,表示非压缩BCD码9 aad ;二进制扩展:ax=68=0044h
div bl ;除法运算:商al=07h,余数ah=05h ;实现非压缩BCD码除法:68=7×9+5 例2.28a:逻辑与运算
mov al,45h
and al,31h ;al=01h,CF=OF=0、SF=0、ZF=0、PF=0 观察CF, OF是否=0, SF、ZF和PF状态,而对AF未定义。 例2.28b:将BL中D0和D3清0,其余位不变 and bl,11110110b 例2.29a:逻辑或运算
mov al,45h
or al,31h ;al=75h,CF=OF=0、SF=0、ZF=0、PF=0 例2.29b:将BL中D0和D3置1,其余位不变 or bl,00001001b 例2.30a:逻辑异或运算
mov al,45h
xor al,31h ;al=74h,CF=OF=0、SF=0、ZF=0、PF=1 例2.30b:将BL中D0和D3求反,其余位不变 xor bl,00001001b
XOR指令经常给寄存器清0,同时使CF也清0;例如: xor ax,ax ;ax=0,CF=OF=0、SF=0、ZF=1、PF=1 例2.31:逻辑非运算 mov al,45h
not al ;al=0bah,观察NOT 指令不影响标志位
例2.32:TEST指令用于测试某一(几)位是否(同时)为0或为1。 test al,01h ;测试AL的最低位D0
jnz there ;标志ZF=0,即D0=1,则程序转移到there ... ;否则ZF=1,即D0=0,顺序执行 there: ...
例2.33:移位指令的功能
mov cl,4
mov al,0f0h ;al=f0h
shl al,1 ;al=e0h,CF=1,SF=1、ZF=0、PF=0,OF=0 shr al,1 ;al=70h,CF=0,SF=0、ZF=0、PF=0、OF=1 sar al,1 ;al=38h,CF=0,SF=0、ZF=0、PF=0、OF=0
sar al,cl ;al=03h,CF=1,SF=0、ZF=0、PF=1
;移位指令按照移入的位设置进位标志CF,根据移位后的结果影响SF、ZF、PF,对AF没有定义。
例2.34:利用移位指令计算DX←3×AX+7×BX,假设为无符号数运算,无进位 mov si,ax
shl si,1 ;si←2×ax add si,ax ;si←3×ax
mov dx,bx mov cl,03h
shl dx,cl ;dx←8×bx sub dx,bx ;dx←7×bx
add dx,si ;dx←7×bx+3×ax
例2.35:将DX.AX中的32位数值左移一位 shl ax,1 rcl dx,1
例2.36:把AL最低位送BL最低位,但保持AL不变
ror bl,1 ror al,1 rcl bl,1
rol al,1
例2.37:AH/AL分别存放着非压缩BCD码的两位,现将它们合并成为一个压缩BCD码存入AL
mov cl,4
rol ah,cl ;也可以用shl ah,cl add al,ah ;也可以用or al,ah
表2.2 条件转移指令中的条件cc
助记符 标志位 说明
助记符 标志位 说明
JZ/JE ZF=1 等于零/相等 JC/JB/JNAE CF=1 进位/低于/不高于等于 JNZ/JNE ZF=0 不等于零/不相等 JNC/JNB/JAE CF=0 无进位/不低于/高于等于 JS SF=1 符号为负 JBE/JNA CF=1或ZF=1 低于等于/不高于
JNS SF=0 符号为正 JNBE/JA CF=0且ZF=0 不低于等于/高于
JP/JPE PF=1 “1”的个数为偶 JL/JNGE SF≠OF 小于/不大于等于 JNP/JPO PF=0 “1”的个数为奇 JNL/JGE SF=OF 不小于/大于等于 JO OF=1 溢出 JLE/JNG ZF≠OF或ZF=1 小于等于/不大于 JNO OF=0 无溢出 JNLE/JG SF=OF且ZF=0 不小于等于/大于
例2.38:如果AL最高位为0,则设置AH=0;如果AL最高位为1,则设置AH=FFh(也就是用一段程序实现符号扩展指令CBW的功能)使用“不等于零转移JNZ指令”: test al,80h ;测试最高位
jz next0 ;最高位为0(ZF=1),转移到next0 mov ah,0ffh ;最高位为1,顺序执行 jmp done ;无条件转向done next0: mov ah,0
done: ...
上述程序段也可以用“等于零转移JZ指令”:
test al,80h ;测试最高位
jnz next1 ;最高位为1(ZF=0),转移到next1 mov ah,0h ;最高位为0,顺序执行 jmp done ;无条件转向done next1: mov ah,0ffh
done: ...
例2.39:计算|X-Y|,X和Y为存放于X单元和Y单元的16位操作数,结果存入result。 mov ax,X
sub ax,Y ;AX←X-Y,下面求绝对值
jns nonneg ;为正数,无需处理,直接转向保存结果 neg ax ;为负数,进行求补得到绝对值
nonneg: mov result,ax ;保存结果
例2.41:设字符的ASCII码在AL寄存器中,将字符加上奇校验位 and al,7fh ;最高位置“0”,同时判断“1”的个数 jnp next ;个数已为奇数,则转向next or al,80h ;否则,最高位置“1” next: ...
例2.42:记录BX中1的个数 xor al,al
again: test bx,0ffffh ;等价于 cmp bx,0
je next
shl bx,1 ;还可以用哪个(循环)移位指令实现? jnc again
inc al jmp again
next: ... ;AL保存1的个数
四、思考题
计算机病毒感染可执行文件的方法是把自已的代码放到可执行文件中,当执行被感染程序时,病毒程序也同时被执行,通过几个实验,对程序执行的过程已有初步了解,试分析前面病毒测试程序,是不是能检测到所有的病毒感染?
五、选做题
有兴趣的同学,可对以上程序进一步完善,把它编成一个有实用意义的应用程序。
因篇幅问题不能全部显示,请点此查看更多更全内容