实验2 多个逻辑段的汇编源程序编写与调试

Posted on 2021-11-06 13:12  小陶要努力  阅读(90)  评论(0编辑  收藏  举报
一、实验目的
1. 理解和掌握8086多个逻辑段的汇编源程序
2. 理解和熟练应用灵活的寻址方式
3. 通过汇编指令loop的使用理解编程语言中循环的本质,掌握其在嵌套循环中的正确使用
4. 掌握使用debug调试8086汇编程序的方法
 
二、实验准备
复习教材5-8章:
包含多个逻辑段的汇编源程序结构
寻址方式
汇编指令loop, div用法
 
三、实验内容
1. 实验任务1
任务1-1
task1_1.asm
assume ds:data, cs:code, ss:stack

data segment
    db 16 dup(0)  ; 预留16个字节单元,初始值均为0
data ends

stack segment
    db 16 dup(0) ;预留16个字节单元,初始值均为0 
stack ends 
code segment
start:
    mov ax, 
    data mov ds, ax 
    mov ax, stack 
    mov ss, ax 
    mov sp, 16 ; 设置栈顶 
    mov ah, 4ch 
    int 21h 
code ends 
end start 

在debug中执行到line17结束、line19之前

 

 

① 在此时DS=076A,SS=076B,CS=076C
② 假设程序加载后,code段的段地址是X,则,data段的段地址是X-2, stack的段地址是X-1。
任务1-2
task1_2.asm
assume ds:data, cs:code, ss:stack 

data segment 
    db 4 dup(0) ; 预留4个字节单元,初始值均为0 
data ends
 
stack segment 
    db 8 dup(0) ; 预留8个字节单元,初始值均为0 
stack ends 
code segment 
start:
    mov ax, data 
    mov ds, ax 
    mov ax, stack 
    mov ss, ax 
    mov sp, 8 ; 设置栈顶 
    mov ah, 4ch 
    int 21h 
code ends 
end start

在debug中执行到line17结束、line19之前

 

① 在此时DS=076A,SS=076B,CS=076C
② 假设程序加载后,code段的段地址是X,则,data段的段地址是X-2, stack的段地址是X-1。
 
任务1-3
task1-3.asm
assume ds:data, cs:code, ss:stack 

data segment 
    db 20 dup(0) ; 预留20个字节单元,初始值均为0 
data ends 

stack segment 
    db 20 dup(0) ; 预留20个字节单元,初始值均为0 
stack ends 
code segment 
start:
    mov ax, data 
    mov ds, ax 
    mov ax, stack 
    mov ss, ax 
    mov sp, 20 ; 设置初始栈顶 
    mov ah, 4ch 
    int 21h 
code ends 
end start 

在debug中执行到line17结束、line19之前

 

① 在此时DS=076A,SS=076C,CS=076E
② 假设程序加载后,code段的段地址是X,则,data段的段地址是X-4, stack的段地址是X-2。
任务1-4
task1-4.asm
assume ds:data, cs:code, ss:stack 
code segment 
start:
    mov ax, data 
    mov ds, ax 
    mov ax, stack 
    mov ss, ax 
    mov sp, 20 
    mov ah, 4ch 
    int 21h 
    code ends 

data segment 
    db 20 dup(0) 
data ends 
   
stack segment 
    db 20 dup(0) 
stack ends 

end start

在debug中执行到line17结束、line19之前

 

① 在此时DS=076C,SS=076E,CS=076A
② 假设程序加载后,code段的段地址是X,则,data段的段地址是X+2, stack的段地址是X+4。
 
任务1-5
① 对于如下定义的段,程序加载后,实际分配给该段的大小是 N/16(向上取整) 字节
xxx segment 
    db N dup(0) 
xxx ends

 

②将所有伪指令end start改成end
task1_1不能正确执行

 

task1_2不能正确执行

 

 task1_3不能正确执行

 

 task1_4可以正确执行

 

 原因是在end start改成end之后,前三个代码段开头是数据段,无法找到程序的入口,cs:ip指向了数据段,把数据当作指令来执行,所以会发生错误;task1_4的程序开头为code段,所以可以找到程序的入口,程序正常。

 

2.实验任务2

 实验代码task2.asm

assume cs:code
code segment
    mov ax,0b800h
    mov ds,ax
    mov bx,0f00h
    mov cx,80
s:  mov al,03h
    mov [bx],al
    inc bx
    mov al,04h
    mov [bx],al
    Inc bx
    loop s

    mov ah,4ch
    int 21h
code ends
end 

代码运行结果

 

实验任务3

 补充后的task3.asm源码

assume cs:code
data1 segment
    db 50, 48, 50, 50, 0, 48, 49, 0, 48, 49 ; ten numbers
data1 ends

data2 segment
    db 0, 0, 0, 0, 47, 0, 0, 47, 0, 0       ; ten numbers
data2 ends

data3 segment
    db 16 dup(0)
data3 ends

code segment
start:
    mov bx, 0
    mov cx, 10

s: mov dx, 0 mov ax, data1 mov ds, ax add dl, [bx] mov ax, data2 mov ds, ax add dl, [bx] mov ax, data3 mov ds, ax add [bx], dl inc bx loop s mov ah, 4ch int 21h code ends end start

代码运行结果

反汇编结果:

运行前的内存情况

 

 将代码成功运行之后的内存情况如下图

 

 可以看到第一行的日期和第二行的/成功相加,日期只间存在/

 

实验任务4

 task4.asm源码

assume cs:code

data1 segment
    dw 2, 0, 4, 9, 2, 0, 1, 9
data1 ends

data2 segment
    dw 8 dup(?)
data2 ends

code segment
start:
    
    mov ax, data1
    mov ds, ax
    mov ax, data2
    mov es, ax
    mov ss, ax
    mov sp, 32

    mov bx, 0
    mov cx, 8
s1: push [bx]
    add bx, 2
    loop s1

    mov bx,16
    mov cx, 8
s2: pop  [bx]
    add bx, 2
    loop s2

    mov ah, 4ch
    int 21h
code ends
end start

反汇编结果:

 

运行之前的内存

 代码运行后的内存

 

 可以看到data1 中的八个数字成功的逆序输入到 了data2中

 

 

实验任务5

 task5.asm源码

assume cs:code, ds:data 
data segment 
    db 'Nuist' 
    db 2, 3, 4, 5, 6 
data ends 

code segment 
start: 
    mov ax, data 
    mov ds, ax 
    mov ax, 0b800H 
    mov es, ax 
    mov cx, 5 
    mov si, 0     
    mov di, 0f00h 
s: mov al, [si] 
    and al, 0dfh 
    mov es:[di], al 
    mov al, [5+si] 
    mov es:[di+1], al 
    inc si 
    add di, 2 
    loop s 
    
    mov ah, 4ch 
    int 21h 
code ends 
end start 

 代码运行后的结果:

 

 可以看到输出了彩色的NUIST

使用g命令将程序执行到line27之前

 

 在源码中line19的作用是利用and运算,将小写的uist变成大写

更改line4代码为

db 5 dup(2)

代码输出结果是

 

 与原来的代码中的第一个N的颜色相同,同时对应原来line4中的第一个数字2,猜测2为绿色

因此line4的数值的作用是控制NUIST的颜色

 

 实验任务6

task6.asm源码

assume cs:code, ds:data

data segment
    db 'Pink Floyd      '
    db 'JOAN Baez       '
    db 'NEIL Young      '
    db 'Joan Lennon     '
data ends

code segment
start:
    mov ax,data
    mov ds,ax
    mov bx,0
    mov cx,4
s:  mov al,[bx]
    or al,20h
    mov [bx],al
    add bx,16
    loop s

   mov ah, 4ch
   int 21h
code ends
end start

反汇编结果

 

 

 

 程序运行前的结果:

 

 

程序运行后:

 

 可以看到开头的四个大写字母全都变成了小写

 

实验任务7

task7.asm源码

assume cs:code, ds:data, es:table

data segment
    db '1975', '1976', '1977', '1978', '1979' 
    dw  16, 22, 382, 1356, 2390
    dw  3, 7, 9, 13, 28 
data ends

table segment
    db 5 dup( 16 dup(' ') )  ;
table ends

code segment
start:
    mov ax, data
    mov ds, ax
    mov ax, table
    mov es, ax

    mov bx, 0
    mov bp, 0
    mov cx, 5
years:
    mov ax, ds:[bx]
    mov es:[bp], ax
    mov ax, ds:[bx+2]
    mov es:[bp+2], ax
    add bx, 4
    add bp, 10h
loop years

    mov bp, 5
    mov cx, 5
income:
    mov ax, ds:[bx]
    mov es:[bp], ax
    add bx, 2
    add bp, 10h
loop income

    mov cx, 5
    mov bp, 10
people:
    mov ax, ds:[bx]
    mov es:[bp], ax
    add bx, 2
    add bp, 10h
loop people

    mov cx, 5
    mov bp, 5
average:
    mov ax, es:[bp]
    mov bl, es:[bp+5]
    div bl
    mov es:[bp+8], al
    add bp,10h
loop average

    mov ah, 4ch
    int 21h
code ends
end start

 

 table原始数据信息:

 

程序运行结果

要求的信息结构化的写入了table中

 

四、实验总结

 通过这次的实验

1.我更加理解了数据存储在内存中的形式,理解了db,dw的不同。

2.同时我复习了并且巩固了div的用法,在32位除以16位以及16位除以8位时div的区别。

3.亲自动手实践了编写了利用and或者or运算,转换大小写

4.通过巩固复习了解到,end start指明了程序的入口,去掉start可能会导致程序的错误

 

Copyright © 2024 小陶要努力
Powered by .NET 9.0 on Kubernetes