汇编语言简明教程 实验报告

汇编语言简明教程 实验报告

提示:本文是应燕山大学实验要求,经抓耳挠腮大量掉发查阅资料后所得


前言

提示:以下是本篇文章正文内容,实验一、二是在DOSBOX窗口中直接编写指令,实验三、四、五是在MASMPlus中编写的。

实验一 汇编语言源程序的输入

1.1实验内容

本实验要求在DEBUG状态下输入汇编源程序,并用DEBUG命令进行调试。用单步跟踪的方法验证指令的功能。

1.2实验过程

-a开始输入指令
-t按步执行指令,查看执行完一条指令,屏幕显示所有寄存器内容和下一条指令地址和指令
查找对应寄存器或内存地址的数据
直接连续输入指令之后,-t查找就可

1.3实验结果

图1.3.1实验结果图1.3.2实验结果

实验二 数 据 的 建 立 与 传 送 程 序

2.1实验内容

在DEBUG状态下,分别输入下面各程序段,每输入完一个程序段,用G命令进行连续方式执行程序,在连续执行时,要记录程序的执行结果。将一段从小到大又从大到小的数据存储,又传递给其他的数据段。

2.2实验过程

1.第一段程序指令:令cx等于数据块的个数31,是根据数据地址循环递增进行传递数据;
2.第二段程序指令:MOVSB字符串传送指令,指令按字节进行传送地址,通过SI和DI两个寄存器控制字符串的源地址和目的地址,将DS:SI这段地址中字节复制到ES:DI指向的地址。
3.第三第四段程序指令:在使用REP MOVSB指令中,将位于DS段的由SI所指向的存储单元的字节或字传送给位于ES段的由DI所指出的存储单元,修改SI和DI,从而指向下一个元素,其中CLD和STD都是用于串操作指令中操作方向标志位DF,CLD设置DF复位,即DF=0,STD设置DF置位,即DF=1。
4.注意跳转指令。
5.-g命令完成指令执行结束指令时,需要-g=XXXX XXXX,前一个地址是运行的程序开始的地址,后一个地址是程序运行结束的地址,否则,会遇到程序运行卡住的问题。

2.3实验结果

1.在内存10000H单元开始,建立00H~0FH~00H 31个数,要求00H~0FH数据逐渐增大,0FH~00H逐渐减小。该程序从内存CS:0100H地址开始输入。
代码如下(示例):

MOV    AX, 1000H
MOV    DS, AX
MOV    SI, 0
MOV    CL, 0FH
XOR    AX, AX
PPE1: MOV    [SI], AL
        INC     SI
INC     AL
DEC     CL
JNZ     PPE1
MOV    CX, 10H
PPE2: MOV    [SI], AL
INC     SI
DEC     AL
LOOP   PPE2
INT     20H

结果(示例):
图2.6.1 内存数据块图
2.把上一个程序的执行结果(建立的31个字节数据块,其首地址在10000H),分几种方式传送到以下指定的区域。
(a)检查内存数据块的传送情况,可用“D”命令。
代码如下(示例):

MOV     AX, 1000H
MOV     DS, AX
MOV     SI, 0
MOV     DI, 5050H
MOV     CX, 1FH         ; 数据块长度是31
PPEA:   MOV     AL, [SI]
MOV     [DI], AL
INC      SI
INC      DI
LOOP    PPEA
INT      20H

内存数据块如下(示例):
图2.6.2 内存数据块图
(b)用串传送指令MOVSB,把数据块传送到15150H开始的区域,该程序从内存CS:0200H开始输入。
代码如下(示例):
图2.6.3 传送代码图
检查程序最后的执行结果,可用“D”命令,例如:
-D1000:5150↙
内存数据块如下(示例):
图2.6.4 内存数据块图
©用重复串操作指令“REP MOVSB”把数据块传送到15250H开始的区域。该程序从CS:250H地址开始输入。

指令代码如下(示例):
图2.6.5传送代码图
检查程序的最后执行结果时,可用:
-D1000: 5250↙
内存数据块如下(示例):
图2.6.6 内存数据块图

(d)用串操作的减量工作方式,把数据块传送到25050H开始的区域。该程序从CS:0300H开始输入。

指令代码如下(示例):图2.6.7 传送代码图
检查程序的最后执行结果,用D命令:
-D2000:5050↙
内存数据块如下(示例):
图2.6.8 内存数据块图

实验3 分 支 程 序 设 计

3.1实验内容

3.1.1给出三个有符号数,编写一个比较相等关系的程序
(1)如果这三个数都不相等,则显示0;
(2)如果这三个数中有两个数相等,则显示1;
(3)如果这三个数都相等,则显示2;
3.1.2找出字符串的大写字母和小写字母
从键盘上输入一串字符到输入缓冲区,找出其中的大写字母和小写字母,并分别统计它们的个数,结果放到变量num1和num2中,要求在屏幕输出显示所有字母及变量num1和num2的值。

3.2实验过程

CMP比效指令
INC加一指令
DEC减一指令
JNB 大于等于
JNBE 大于
LOOP 循环控制指令
在输出字符串的时候,需要有“$”才可以停止输出字符串
输入有符号的字符串以及直接输出十进制数字时,引入含有调用输入输出子程序的声明语句和宏定义的文件io.inc。

3.3实验结果

3.3.1
指令代码如下(示例):

include io.inc
.model small
.stack
.data
msg1 db 10,13,'Please input var1:$'
msg12 db 10,13,'Please input var2:$'
msg13 db 10,13,'Please input var3:$'
msg2 db 10,13,'Please ouput:$'
msg3 db 10,13,'$'
var1 db ?
var2 db ?
var3 db ?
.code
.startup
mov dx,offset msg1;提示输入字符串
mov ah,9
int 21h
call readsib;输入第一个字符
mov var1,al
mov bl,var1
mov dx,offset msg12;提示输入字符串
mov ah,9
int 21h
call readsib;输入第二个字符
mov var2,al
mov cl,var2
mov dx,offset msg13;提示输入字符串
mov ah,9
int 21h
call readsib;输入第三个字符
mov var3,al
mov al,var3
mov dx,offset msg2;输出结果
mov ah,9
int 21h
mov dl,0;记录最终结果
cmp bl,cl
jne one;若不相等跳转
inc dl;若相等加一
one:cmp al,cl
jne two
inc dl
two:cmp bl,al
jne three
inc dl
three:cmp dl,3h
jne last
dec dl
last:add dl,30h
mov ah,02h
int 21h
end
```bash

指令代码检测结果如下(示例):
程序检测
程序检测
程序检测

3.3.2
指令代码如下(示例):

include io.inc
.model small
.stack
.data
buffer db 60;字符串所占的字节数
     db ?;输入字符串字符个数,自动填充
     db  60 dup(0);数组存储输入字符串
msg1 db 10,13,'Please input:$'
msg2 db 10,13,'varL:$'
msg3 db 10,13,'varS:$'
msg4 db 10,13,'$'
msg5 db 10,13,'Please ouput:$'
varL db 0;大写字母个数
varS db 0;小写字母个数
.code
.startup
mov dx,offset msg1;提示输入字符
mov ah,9
int 21h
lea dx,buffer;输入字符串
mov ah,0ah
int 21h
mov bl,buffer+1;若为空
cmp bl,0
jz exit
lea si,buffer+2;两个字节代表一个字
mov cl,bl
again:
mov al,BYTE ptr[si]
cmp al,'z'
jnbe next;比z大,跳过
cmp al,'a';比z小
jnb number2;大于等于a,小写字母数字增加
cmp al,'Z';比a小
jnbe next;比Z大,跳过
cmp al,'A';比Z小
jnb number1;大于等于A
jmp next;比A小,跳过
number1:inc varL
jmp next
number2:inc varS
jmp next
next:inc si
loop again
mov bh,0
add bx,dx
mov BYTE ptr[bx+2],'$'
mov buffer,13
mov buffer+1,10
exit:
mov ah,9
int 21h
mov dx,offset msg2;大写字母个数
mov ah,9
int 21h
mov al,varL
 call dispsib
mov dx,offset msg3;小写字母个数
mov ah,9
int 21h
mov al,varS 
call dispsib
end

指令代码检测结果如下(示例):
程序检测
程序检测

实验4 分 支 程 序 设 计

4.1实验内容

设有 10 个学生的成绩分别为 56、69、84、82、73、88、99、63、100 和 80 分。试编制程序分别统计低于 60 分、60~69 分、70~79 分、80~89 分、90~99 分及 100 分的人数存放到 s5、s6、s7、s8、s9 及 s10 单元中。这一题目的算法很简单,成绩分等部分采用分支结构,统计所有成绩则用循环结构完成。

4.2实验过程

注意dw与db所占的字节不同,dw占据内存两个字节,db占据内存一个字节,在循环程序中,改变的量——所加的偏移地址是目标字符串的类型。编写将存放于 S5、S6、S7、S8、S9 及 S10 单元中的数据在屏幕上显示出来的部分程序。

4.3实验结果

指令代码如下(示例):

;PROGRAM TITLE GOES HERE――result 
;************************************ 
DATAREA           SEGMENT         ;DEFINE DATA SEGMENT 
GRADE                DW            56,69,84,82,73,88,99,63,100,80 
S5                     DW                       0 
S6                     DW                       0 
S7                     DW                       0 
S8                     DW                       0 
S9                     DW                       0 
S10                    DW                       0 
DATAREA ENDS 
;************************************ 
PROGNAM SEGMENT                 ;DEFINE CODE SEGMENT 
;---------------------------- 
MAIN       PROC      FAR          ; MAIN PART OF PROGRAM 
ASSUME CS:PROGNAM, DS:DATAREA 
START:                             ; STARTING EXECUTION ADDRESS 
; SET UP STACK FOR RETURN 
PUSH       DS         ; SAVE OLD DATA SEGMENT 
SUB        AX,AX      ; PUT ZERO IN AX 
PUSH       AX         ; SAVE IT ON STACK 
; SET DS REGISTER TO CURRENT DATA SEGMENT 
MOV      AX,DATAREA   ; DATAREA SEGMENT ADDR 
MOV      DS,AX         ; INTO DS REGISTER 
; MAIN PART OF PROGRAM GOES HERE 
MOV      S5, 0           ; INITIALIZE COUNTER 
MOV      S6, 0 
MOV      S7, 0 
MOV      S8, 0 
	            MOV      S9, 0 
MOV      S10, 0 
MOV      CX, 10        ; INITIALIZE LOOP COUNT VALUE 
MOV      BX, OFFSET GRADE ; INITIALIZE FIRST ADDR12 
COMPARE:
MOV      AX,[BX]      ; GET A RESULT 
CMP      AX, 60        ; <60? 
JL        FIVE 
CMP      AX, 70        ; <70? 
JL        SIX 
CMP      AX, 80        ; <80? 
JL        SEVEN 
CMP      AX, 90        ; <90? 
JL        EIGHT 
CMP      AX, 100       ; =100? 
JNE       NINE 
INC       S10 
JMP       SHORT CHANGE_ADDR 
NINE: INC       S9 
JMP       SHORT CHANGE_ADDR 
EIGHT: INC      S8 
JMP       SHORT CHANGE_ADDR 
SEVEN: INC      S7 
JMP       SHORT CHANGE_ADDR 
SIX:  INC        S6 
JMP       SHORT CHANGE_ADDR 
FIVE: INC        S5
CHANGE_ADDR: 
ADD       BX, 2 
LOOP        COMPARE 
MOV CX,6;设置6个成绩阶段
MOV SI,OFFSET S5;从S5开始输出
AGAIN:MOV DX,[SI];
ADD DX,30H;将数字转化为字符
MOV AH,02;调用02号ah输出字符
INT 21H;
MOV DL,20H;在屏幕上显示空格(20h)
MOV AH,02;调用02号ah输出字符
INT 21H
ADD SI,2;一个Sx是dw类型,占据两个字节
LOOP AGAIN;
RET                               ; RETURN TO DOS 
MAIN    ENDP                     ; END OF MAIN PART OF PROGRAM 
; ------------------------------ 
PROGNAM ENDS 
;*************************** 
END         START           ; END ASSEMBLY

指令执行结果如下(示例):
程序结果

实验5 学 生 成 绩 名 次 表 实 验

5.1实验内容

将 0~100 之间的 10 个成绩存入首址为 1000H 的单元中。1000H+i 表示学号为 i 的学生成绩,编写程序能在 2000H 开始的区域排出名次表。2000H+i 为学号 i 的学生的名次。

5.2实验过程

调用子程序,将十六进制转化为十进制,对数值进行除10求余压栈,最后再逐一出栈进行显示,需要注意的是入口参数是ax,而数值是al,需要将al进行符号数扩展后,再调用子程序。

5.3实验结果

指令代码如下(示例):

include io.inc
CRLF    MACRO
MOV     DL, 0DH
MOV     AH, 02H;回车
INT      21H
MOV     DL, 0AH
MOV     AH, 02H;换行
INT      21H
ENDM
DATA     SEGMENT
STUNUM  EQU       10
MESS   DB   'INPUT 10 STUDENTS SCORE: ',0DH,0AH,'$';提示输入10位同学的成绩
ERROR  DB   'INPUT ERROR!',0DH,0AH,'$';提示输入错误
ORG      1000H
SCORE    DB  10 DUP (?);成绩
  ORG    2000H
SEQU     DB   10 DUP (?)
DATA     ENDS
STACK    SEGMENT
STA      DW         12 DUP (?)
TOP      DW         ?
STACK   ENDS
CODE    SEGMENT
ASSUME  CS:CODE,DS:DATA,ES:DATA,SS:STACK
START:    MOV       AX, DATA
           MOV        DS, AX
           MOV        ES, AX
           MOV        SP, TOP            ; 初始化
           MOV       DX, OFFSET MESS
           MOV        AH, 09H
           INT        21H                ; 显示提示输入信息
           MOV       SI, OFFSET SCORE  ; 成绩表首址
           MOV       CX, STUNUM       ; 学生数送CX
UUU:     CALL      GETNUM           ; 读取键入数值送DX
          MOV       [SI], DL             ; 存入成绩表缓冲区
          INC        SI                  ; 指向下一单元
          LOOP      UUU
          MOV       CX, STUNUM       ; 学生数
          MOV       DI, OFFSET SEQU    ; 名次表首址
VVV:     CALL      SCAN               ; 扫描子程序
          MOV       AL, STUNUM        ; 学生数
          SUB       AL, CL
          INC        AL                 ; 计算名次
         MOV       BX, DX 
         MOV       [DI+BX], AL        ; 记DX学号对应名次
         LOOP      VVV
         MOV       CX, STUNUM       ; 学生数
         MOV       SI, OFFSET SEQU    ; 名次表首址
WWW:   MOV       AL, [SI]  
         CALL       DISP1
         CRLF
         INC        SI
         LOOP      WWW              ; 显示排定的学生名次
         MOV       AX, 4C00H
         INT       21H
SCAN    PROC      NEAR          ; 子程序,每扫描一遍成绩表缓冲区, 找出其中成绩最高者由DX指针指示对应学生 之后将该成绩清除,以便下一次扫描
PUSH     CX
MOV     CX, STUNUM          ;学生数
MOV     AL, 00H                  ;最低成绩
MOV     BX, OFFSET SCORE
MOV     SI, BX                   ;指向成绩表首址
CCC:       
CMP      AL, [SI]
JAE JJJ;AL中的成绩不低于成绩表指针SI所指单元的成绩则转JJJ
MOV      AL, [SI]               ;AL存放较高的成绩
MOV      DX, SI 
SUB       DX, BX                    ;DX为对应学号
JJJ:INC     SI                        ;指向下一单元
LOOP      CCC
ADD       BX, DX
MOV       BYTE PTR[BX], 00H        ;本次扫描成绩最高者清0          
POP        CX
RET
SCAN       ENDP
DISP1       PROC     NEAR
            PUSH     CX
            MOV      BL, AL
            MOV      DL, BL
            MOV      CL, 04
            ROL      DL, CL
            AND      DL, 0FH
            CALL     DISPL
            MOV      DL, BL
            AND      DL, 0FH
            CALL     DISPL
            POP      CX
            RET
DISP1       ENDP
DISPL       PROC    NEAR 
JMP  DDD2;将程序跳转到DDD2
DDD2:
MOV AL,DL;将dl中的值传递给al
CBW;子程序传递参数是ax,将al字符扩展到ax
CALL EXCHANGE;调用子程序将16进制转化为10进制
RET
EXCHANGE PROC;
PUSH AX
PUSH BX
PUSH CX
PUSH DX
XOR CX,CX
CMP AX,0
JNE L1;ax不为0
ADD AX,'0';ax为0时特殊处理
PUSH AX
MOV AX,0
MOV CX,1
L1:MOV BL,AL;
ADD BL,AH
CMP BL,0
JNE L2;除10取余数不为0
JMP L3
L2:
MOV DL,10
DIV DL;除10求余保存
MOV BX,0
MOV BL,AH
ADD BL,'0'
PUSH BX;位数加1
INC  CX;商作为被除数继续循环
MOV AH,0
JMP L1
L3:
POP DX;为0跳出
MOV AH,2
INT 21H
LOOP L3
POP DX
POP CX
POP BX
POP AX
JMP EXIT
EXIT:RET
EXCHANGE ENDP
DISPL      ENDP                    
GETNUM   PROC    NEAR
        PUSH      CX
        XOR       DX, DX
GGG:   MOV      AH, 01H
        INT        21H
        CMP       AL, 0DH
        JZ         PPP
        CMP       AL, 20H
        JZ         PPP
        SUB       AL, 30H
        JB         KKK
        CMP       AL, 0AH
        JB         GETS
        CMP       AL, 11H
        JB         KKK
        SUB       AL, 07H
        CMP       AL, 0FH
        JBE        GETS
        CMP       AL, 2AH
        JB         KKK
        CMP       AL, 2FH
          JA         KKK
          SUB       AL, 20H
GETS:    MOV     CL, 04
          SHL       DX, CL
          XOR       AH, AH
          ADD       DX, AX
          JMP       GGG
KKK:     MOV      AH, 09H
          MOV      DX, OFFSET  ERROR
          INT       21H
PPP:      PUSH      DX 
          CRLF
          POP       DX
          POP       CX
          RET
GETNUM  ENDP                   
CODE     ENDS
END       START

指令执行结果如下(示例):
程序结果

总结

以上就是鄙人的汇编语言简明教程2021实验课报告,其中实验实验过程部分是小人在实验过程中遇到的问题,经查资料之后的总结,请各位大人多多指教。
  • 31
    点赞
  • 115
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值