【汇编】实验(上)

实验课作业,实验截图就不放啦~放一些代码

 

实验一:

  1. 实验任务一:将汇编源程序拷贝到汇编集成环境,进行调试,体验汇编程序的运行。

(1) 实验步骤

源程序:

DATAS SEGMENT

    a            db    ?

b            db    ?

k            db    ?

string       db    'k=$'  

DATAS ENDS

 

STACKS SEGMENT

    ;此处输入堆栈段代码

STACKS ENDS

 

CODES SEGMENT

        ASSUME cs:codes, ds:datas,es:datas

start:

main proc far

        push    ds

        sub      ax,ax

        push    ax

        mov     ax,datas

        mov     ds,ax

        mov     es,ax    

        mov   a,1

        mov   b,2

        mov   al,a

        add   al,b

        mov   k,al

        lea   dx,string

        mov   ah,09

        int   21h

        add   k,30h

        mov   dl,k

        mov   ah,2

        int   21h

        mov   dl,0ah

        int   21h

        mov   dl,0dh

        int    21h

        ret

main endp

CODES ENDS

    END START

 

(2) 实验现象

运行结果为k=3.

原有代码存在一些问题,经过修改后代码如上,能够正常运行。

 

2. 实验任务二:DEBUG的使用

 

3. 实验任务三:练习使用DEBUG

 

 

 

 

实验二:

 

1. 实验任务一:七种寻址方式的认识与练习

在代码段里输入指令或在DEBUG里输入指令,然后查看指令运行的结果,看看是否跟自己的设想一致,如有问题,想办法解决

 

1.立即寻址:mov AL,5

 

运行结果:将05写入AL中,AX寄存器中为0705

 

2.寄存器寻址:mov BX,AX

 

运行结果:将AX写入BX中,BX寄存器中为0705

 

3.直接寻址:mov AX,DS:[2000H]未修改2000H的数据,仍为0000H

 

运行结果:将地址为2000H的数据写入AX中,AX寄存器中为0000

4.寄存器间接寻址:mov CX,[BX]debug时输入-e DS:0705,将数据修改为0039h并运行。

 

运行结果:将BX为地址的数据写入CX中,CX寄存器中为0039

 

5.寄存器相对寻址:

mov SI,0065h

 mov AX,3000h[SI]debug时输入-e DS:3065,将数据修改为0078h并运行。

 

运行结果:将[3000+0065]为地址的数据写入AX中,AX寄存器中为0078

6.基址变址寻址:

mov DI,10A5H  mov AX,[BX][DI]将地址为17AAH的数据修改为0034H并运行。

 

运行结果:将[BX+DI]为地址的数据写入AX中,AX寄存器中为0034

 

7.相对基址变址寻址:

mov AX,1000H[BX][DI]将地址为27AAH的数据修改为0019H并运行。

 

运行结果:将[1000+BX+DI]为地址的数据写入AX中,AX寄存器中为0019

 

2. 实验任务二:指令的验证

1)数据传送指令

数据传送指令包括通用数据传送指令、累加器专用传送指令、地址传送指令、标志寄存器传送指令、类型转换指令。

通用数据传送指令包含:

MOV 传送;MOVSX带符号扩展传送;MOVZX 带零扩展传送;PUSH 进栈了;POP 出栈;PUSHA/PUSHAD 所有寄存器进栈;POPA/POPAD 所有寄存器出栈;XCHG 交换。

累加器专用传送指令包含:

IN 输入;OUT 输出;XLAT 换码。

地址传送指令包含:

LEA 有效地址送寄存器;LDS 指针送寄存器和DS;LES 指针送寄存器和ES;LFS 指针送寄存器和FS;LGS 指针送寄存器和GS;LSS 指针送寄存器和SS。

标志寄存器传送指令包含:

LAHF 标志送AH;SAHF AH送标志寄存器;PUSHF/PUSHFD 标志进栈;POPF/POPFD 标志出栈。

类型转换指令包含:

CBW 字节转换为字;CWD/CWDE 字转换为双字;CDQ 双字转换为4字;BSWAP 字节交换。

2)算术指令

算术指令包括加法指令、减法指令、乘法指令、除法指令、十进制调整指令。

加法指令包含:

ADD 加法;ADC 带进位加法;INC 加1;XADD 交换并相加。

减法指令包含:

SUB 减法;SBB 带借位减法;DEC 减1;NEG 求补;CMP 比较;CMPXCHG 比较并交换;CMPXCHG8B 比较并交换8字节。

乘法指令包含:

MUL 无符号数乘法; IMUL 带符号数乘法。

除法指令包含:

DIV 无符号数除法; IDIV 带符号数除法。

3)逻辑指令

逻辑指令包括逻辑运算指令、位测试并修改指令、位扫描指令、移位指令。

逻辑运算指令包含:

AND 逻辑与;OR 逻辑或;NOT 逻辑非;XOR 异或;TEST 测试。

位测试并修改指令包含;

BT 位测试;BTS 位测试并置1;BTR 位测试并置0;BTC 位测试并求反。

位扫描指令包含:

BSF 正向位扫描;  BSR 反向位扫描。

移位指令包含:

SHL 逻辑左移;SAL 算术左移;SHR 逻辑右移SAR 算术右移;ROL 循环左移;ROR 循环右移;RCL 带进位循环左移;RCR 带进位循环右移;SHLD 双精度左移;SHRD 双精度右移。

 

3. 实验任务三:小程序的调试

;给各个寄存器赋值

MOV AX, 1234H

MOV DX, 5678H

;运行代码

MOV BL, DL   ;DX8位赋值给BL

MOV CL, 4    ;CL赋值04

SAR DX, CL    ;DX算术右移4

AND BL,0FH   ;BL0FH相与

SHR AX, CL    ;AX逻辑右移4

ROR BL, CL    ;BL循环右移4

OR AH, BL     ;AHBL相或

 

 

 

最终AX结果为AX=8123H。

 

4. 实验任务四:给出下列各条指令执行后AL值,以及CF、ZF、SF、OF和PF的状态

1)MOV AL, 89H

2)ADD AL, AL

3)ADD AL, 9DH

4)CMP AL, 0BCH

5)SUB AL, AL

6)DEC AL

7)INC AL

 

1)执行后AL值为89H

各标志位为

CFNC(没有进位);     ZFNZ(不是零);

SFPL(符号为正);     OFNV(没有溢出);

PFPO(为奇)。

 

2)执行后AL值为12H

各标志位为

CFCY(进位);      ZFNZ(不是零);

SFPL(符号为正);   OFOV(溢出);

PFPE(为偶)。

 

3)执行后AL值为AFH

各标志位为

CF:NC(没有进位);    ZF:NZ(不为零);

SF:NG(符号为负);    OF:NV(没有溢出);

PF:PE(为偶)。

 

4)执行后AL值为AFH,不变

各标志位为

CFCY(进位);      ZFNZ(不为零);

SFNG(符号为负);  OFNV(没有溢出);

PFPE(为偶)。

 

5)执行后AL值为00H

各标志位为

CFNC(没有进位);   ZFZR(为零);

SFPL(符号为正);    OFNV(没有溢出);

PFPE(为偶)。

 

 

6)执行后AL值为FFH

各标志位为

CFNC(没有进位);  ZFNZ(不为零);

SFNG(符号为负);  OFNV(没有溢出);

PFPE(为偶)。

 

7)执行后AL值为00H

各标志位为

CFNC(没有进位);  ZFZR(为零);

SFPL(符号为正);  OFNV(没有溢出);

PFPE(为偶)。

 

 

实验三:

1. 实验任务一:常用指令练习(结合Debug理解指令功能)

 

 

2. 实验任务二:程序段的编制

下面程序段的功能是什么?执行后CX的值为多少?

MOV CX, 0;

MOV BX, 3456H

repeat:

TEST BX, 0ffffh  

JZ    exit         

JNS   Shift        

INC CX

Shift:  

SHL BX,1

JMP   repeat

exit:

 

 

该程序是一段循环左移的指令,将BX=3456H每次循环左移一位,CX值+1,最终将BX移成0000H为止,CX代表着移动几次,所以最终结果为CX=0007H,代表循环左移7次。

 

 

3. 实验任务三:程序段的编制

设变量字AB的定义如下

A DW 1234H, 5678H

B DW 9A07H, 45C2H

编程序段求AB这两个双字数据的加法,和放在变量B

数据段代码

A DW 1234H,5678H

    B DW 9A07H,45C2H

代码段代码

MOV AX,A

    MOV BX,B

    ADD BX,AX

    MOV B,BX

    MOV AX,A+2

    MOV BX,B+2

    ADD BX,AX

    MOV B+2,BX

 

定义变量字AB,由于存储单元连续,所以按照存储顺序在0000地址内存入了34,在0001地址中存入了120002地址中为780003地址中为56。同理,在00040007地址中,分别是079AC245

我对AB的数据分别进行加法计算,先将1234H9A07H进行加法计算,并把结果覆盖掉00040005地址中的内容,因此00040005地址中的内容为3BAC。同理再对5678H45C2H进行计算,得到9C3AH的计算结果,同样存入45C2H原本的存储单元内,即00060007地址所对应的内存单元中,将其中内容修改为3A9C

因此最后00040007地址中存入的数据为3BAC3A9C,如下图所示。

 

 

 

实验四:

1. 实验任务一:设AL=x,若x<100,AL=AL+50;若x>=100,AL=AL-100,编程实现。

初始值x根据设定改变:

代码如下:

DATAS SEGMEpNT

    Xdb 110

;string       db    'AL=$'  

DATAS ENDS

 

STACKS SEGMENT

    ;此处输入堆栈段代码

STACKS ENDS

 

CODES SEGMENT

        ASSUME DS:datas

start:

main proc far

MOV AX,DATAS

    MOV DS,AX

    

        MOV AL,X

CMP AL,100

JNZ NO1;不等于bai1

SUB AL,100;等于1的程序段du

JMP EXIT

NO1:CMP AL,100

JL XIAOYU

SUB AL,100;大于1的程序段

JMP EXIT

XIAOYU:ADD AL,50 ;小于1的程序段

EXIT:

         ;lea   dx,string

        mov   dl,AL

      

        AAM

        MOV BL,AL

        ADD BL,30H

        ADD AH,30H

        mov   dl,AH

        MOV AH,2

        INT 21H

        mov   dl,BL

        INT 21H

        MOV AH,4CH

        int    21h

        ret

main endp

CODES ENDS

END START

 

2.实验任务:编制程序完成如下两个32位数相加1F98243H + 34567890H

双字运算只有在386及其后继机型可以进行,因此只能在8086中只可以进行16位的运算,因此将两个32位分别分成两个16位二进制进行进位运算。将01F98243H分成高4位01F9H和低四位8243H,将34567890H分成高四位3456H和低四位7890H,先进行低四位的运算8243H+7890H,得到答案FAD3H,并没有产生进位。再进行高四位运算,01F9H+3456H,得到364FH。将这两个16位二进制数存入之后相邻的内存单元,完成运算。

 

代码如下:

DATAS SEGMENT

    A DW 01F9H,8243H

    B DW 3456H,7890H

    CC DW ?

    E DW ?;此处输入数据段代码  

DATAS ENDS

 

STACKS SEGMENT

    ;此处输入堆栈段代码

STACKS ENDS

 

CODES SEGMENT

    ASSUME CS:CODES,DS:DATAS,SS:STACKS

START:

    MOV AX,DATAS

    MOV DS,AX

    

    MOV AX,A+2 ;先进行低四位运算

    MOV BX,B+2

    ADD BX,AX

    MOV CC,BX

    MOV AX,A ;再进行高四位运算

    MOV BX,B

    ADC BX,AX

    MOV E,BX

    

    ;此处输入代码段代码

    MOV AH,4CH

    INT 21H

CODES ENDS

    END START

 

 

 

3.在数据段定义3个字变量AA=200,BB=300,CC,编制程序实现AA和BB相加,结果保存在CC中。

数据段如下

DATAS SEGMENT

    AA DW 100

    BB DW 200

    CC DW ?

;string       db    'AL=$'  

DATAS ENDS

 

 

 

 

 

4.实验任务:编制程序计算以下表达式:Y=(W-X*Z)/(X-2)+100,其中W=100、X=10、Z=2 、Y在数据段定义

由于8086的除法运算要求字节操作为16位被除数在AX中,8位除数为源操作数,结果的8位商在AL中,8位余数在AH中。因此,将W=100定义为字,X=10和Z=2定义为字节。数据段代码如下:

DATAS SEGMENT

    W DW 100

    X DB 10

    Z DB 2

    Y DW ?;此处输入数据段代码  

DATAS ENDS

 

 

 

5.实验任务编程查找字符串STR中是否包含$字符,若包含,KEY单元置1,否则置0

首先自行定义了一串字符串str1为‘ab$d’,KEY和字符串长度,数据段代码如下:

DATAS SEGMENT

    KEY DB ?

    str1 DB 'abd$'

    len1 DW 4

    ;此处输入数据段代码  

DATAS ENDS

 

SI寄存器中存入0,表示正在判断的那一位字符。

SI从0开始进行判断:

先判断SI是否等于len1,若不等于则允许SI+1,若等于len1,则跳转到程序结束。

str1[SI]等于‘$’,则将KEY置1,并结束程序;

str1[SI]不等于‘$’,则SI+1。

代码段代码如下:

CODES SEGMENT

    ASSUME CS:CODES,DS:DATAS,SS:STACKS

START:

    MOV AX,DATAS

    MOV DS,AX

    

    MOV SI,0

    MOV KEY,0

L2: CMP SI,len1 ;SIlen1进行比较,若等于则结束程序

    JZ L1

    

    CMP str1[SI],'$' ;字符与‘$’进行比较

    JZ L3

    ADD SI,1

    JMP L2

    

L3: MOV KEY,1 ;KEY1

    JMP L1

    

L1: MOV AH,4CH ;程序结束

    INT 21H

    

CODES ENDS

    END START

 

 

posted @ 2020-11-17 15:23  carrotmvp  阅读(406)  评论(0编辑  收藏  举报