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

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

实验任务一

任务1-1

对程序task1_1.asm进行汇编、连接,用 debug加载、跟踪调试,基于结果,回答问题。

  • 以下为task1_1.asm源码内容:
//task1_1.asm
assume ds:data, cs:code, ss:stack

data segment
    db 16 dup(0)
data ends

stack segment
    db 16 dup(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
  • 调试到line17结束,line19之前,实验2 多个逻辑段的汇编源程序编写与调试
    输入指令
    -g 000D

    跳转到19行代码前,查看结果:实验2 多个逻辑段的汇编源程序编写与调试

  • 问题回答:记录此时:寄存器(DS)= 076A,寄存器(SS)= 076B,寄存器(CS)= 076C 。假设程序加载后,code段的段地址是X,则,data段的段地址是(x-2), stack的段地址是 (x-1)。

任务1-2

对程序task1_2.asm进行汇编、连接,用debug加载、跟踪调试,基于结果,回答问题。

  • 以下为task1_2.asm源码内容:

 

 1 //task1_2.asm
 2 assume ds:data, cs:code, ss:stack
 3 data segment
 4     db 4 dup(0)
 5 data ends
 6 
 7 stack segment
 8     db 8 dup(0)
 9 stack ends
10 code segment
11 start:
12     mov ax, data
13     mov ds, ax
14 
15     mov ax, stack
16     mov ss, ax
17     mov sp, 8
18 
19     mov ah, 4ch
20     int 21h
21 code ends
22 end start

调试到line17结束,line19之前,输入指令

-g 000D

跳转到19行代码前,查看结果实验2 多个逻辑段的汇编源程序编写与调试

 

 

  • 问题回答:记录此时:寄存器(DS) = 076A, 寄存器(SS) = 076B, 寄存器(CS) = 076C 。假设程序加载后,code段的段地址是X,则data段的段地址是(x-2), stack的段地址是 (x-1)。

任务1-3

对程序task1_3.asm进行汇编、连接,用debug加载、跟踪调试,基于结果,回答问题。

  • 以下为task1_3.asm源码内容:
     1 //task1_3.asm
     2 assume ds:data, cs:code, ss:stack
     3 data segment
     4 db 20 dup(0)
     5 data ends
     6 stack segment
     7 db 20 dup(0)
     8 stack ends
     9 code segment
    10 start:
    11 mov ax, data
    12 mov ds, ax
    13 
    14 mov ax, stack
    15 mov ss, ax
    16 mov sp, 20
    17 
    18 mov ah, 4ch
    19 int 21h
    20 code ends
    21 end start

 调试到line17结束,line19之前,输入指令

  • -g 000D

    跳转到19行代码前,查看结果:实验2 多个逻辑段的汇编源程序编写与调试

  • 问题回答:记录此时:寄存器(DS) = 076A, 寄存器(SS) = 076C, 寄存器(CS) = 076E 。假设程序加载后,code段的段地址是X,则data段的段地址是(x-4), stack的段地址是 (x-2)。

任务1-4

对程序task1_4.asm进行汇编、连接,用 debug加载、跟踪调试,基于结果,回答问题。

  • 以下为task1_4.asm源码内容:
     1 //task1_4.asm
     2 assume ds:data, cs:code, ss:stack 
     3 code segment 
     4 start:
     5     mov ax, data 
     6     mov ds, ax 
     7 
     8     mov ax, stack 
     9     mov ss, ax 
    10     mov sp, 20 
    11 
    12     mov ah, 4ch 
    13     int 21h 
    14 code ends 
    15 
    16 data segment 
    17     db 20 dup(0) 
    18 data ends 
    19 
    20 stack segment 
    21     db 20 dup(0) 
    22 stack ends 
    23 
    24 end start
  • 调试到line17结束,line19之前,输入指令
    -g 000D

    跳转到19行代码前,查看结果:实验2 多个逻辑段的汇编源程序编写与调试

     

  • 问题回答:记录此时:寄存器(DS)= 076C,寄存器(SS)= 076E,寄存器(CS)= 076A 。假设程序加载后,code段的段地址是X,则,data段的段地址是(x+2), stack的段地址是 (x+4)。

任务1-5

基于上述四个实验任务的实践、观察,总结并回答:

  1. 对于如下定义的段,程序加载后,实际分配给该段的内存空间大小是:max{16,N}b 。
    1 xxx segment
    2       db N dup(0)
    3 xxx ends
  2. 如果将程序task1_1.asm, task1_2.asm, task1_3.asm, task1_4.asm中,伪指令 end start 改成 end , 发现task1_4.asm可以正确执行,task1_1.asm, task1_2.asm, task1_3.asm 则不能正确执行。分析:task1_4.asm可以正确执行,task1_1.asm, task1_2.asm, task1_3.asm 不能正确执行,因为end start改为end,程序没有标出程序段结束位置,因此无法配对开始位置,task1_4.asm以程序段开始,可以正常运行,task1_1.asm, task1_2.asm, task1_3.asm 以数据段开始,无法识别是否为程序段,因此无法运行。

实验任务二

编写一个汇编源程序,实现向内存单元b800:0f00——b800:0f9f连续160字节,依次重复填充十六进制数据03 04。

  • 以下为实验任务二设计代码 task2.asm:
 1 //task2.asm
 2 assume cs:code
 3 
 4 code segment
 5 start:
 6     mov ax,0b800h
 7     mov ds,ax
 8     mov bx,0f00h
 9     mov cx,80
10 
11 s:  mov [bx],0403h
12     add bx,2
13     loop s
14 
15     mov ah, 4ch
16     int 21h
17 code ends
18 end start
  • 生成exe文件,测试运行结果如下:

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

 一排❤

实验任务三

已知8086汇编源程序task3.asm代码片段如下:

 1 //task3.asm
 2 assume cs:code
 3 data1 segment
 4     db 50, 48, 50, 50, 0, 48, 49, 0, 48, 49 ; ten numbers
 5 data1 ends
 6 
 7 data2 segment
 8     db 0, 0, 0, 0, 47, 0, 0, 47, 0, 0       ; ten numbers
 9 data2 ends
10 
11 data3 segment
12     db 16 dup(0)
13 data3 ends
14 
15 code segment
16 start:
17    ; ×××
18 code ends
19 end start

要求:

  1. 编程实现把逻辑段data1和逻辑段data2的数据依次相加,结果保存到逻辑段data3中。
     1 //补充代码
     2 code segment
     3 start:
     4     mov ax,data1
     5     mov ds,ax
     6 
     7     mov bx,0
     8     mov cx,5
     9 s:  mov ax,[bx]
    10      add ax,[bx+16]
    11     mov [bx+32],ax
    12     add bx,2
    13     loop s

     

  2. 在debug中加载、反汇编、调试。在数据项依次相加前,和相加后,分别查看三个逻辑段data1,data2, data3对应的内存空间,确认逐一相加后,结果的确保存在了逻辑段data3中。查看逻辑段data1,data2,data3对应的内存空间数据原始值的debug命令和截图:实验2 多个逻辑段的汇编源程序编写与调试
    以下为相加前data1、2、3逻辑段对应的内存空间截图:

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

     运行命令:

    1 -g 0018

    再次查看相加后逻辑段data1,data2,data3对应的内存空间数据,确认逐一相加后结果的确保存在了逻辑段data3中。

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

实验任务四

已知8086汇编源程序task4.asm代码片段如下:

 1 assume cs:code
 2 
 3 data1 segment
 4     dw 2, 0, 4, 9, 2, 0, 1, 9
 5 data1 ends 
 6 
 7 data2 segment
 8     dw 8 dup(?)
 9 data2 ends
10 stack segment
11     db 16 dup(0)
12 stack ends
13 code segment
14 start:
15     
16     ; xxx
17     mov ah, 4ch
18     int 21h
19 code ends
20 end start
  • 补全程序:
 1 code segment
 2 start:
 3     mov ax, data1
 4     mov ds, ax
 5     mov ax, data2
 6     mov ss, ax  ;
 7     mov sp, 10h ;
 8     mov bx, 0
 9     mov cx, 8
10 s:  push [bx]
11     add bx, 2
12     loop s
13 
14     mov ah, 4ch
15     int 21h
16 code ends
17 end start

在debug中加载、反汇编、调试:实验2 多个逻辑段的汇编源程序编写与调试

  • 程序退出前,使用d命令查看数据段data2对应的内存空间:实验2 多个逻辑段的汇编源程序编写与调试

实验任务五

 录入源代码:

 1 assume cs:code, ds:data
 2 data segment
 3         db 'Nuist'
 4         db 2, 3, 4, 5, 6
 5 data ends
 6 
 7 code segment
 8 start:
 9         mov ax, data
10         mov ds, ax
11 
12         mov ax, 0b800H
13         mov es, ax
14 
15         mov cx, 5
16         mov si, 0
17         mov di, 0f00h
18 s:      mov al, [si]
19         and al, 0dfh
20         mov es:[di], al
21         mov al, [5+si]
22         mov es:[di+1], al
23         inc si
24         add di, 2
25         loop s
26 
27         mov ah, 4ch
28         int 21h
29 code ends
30 end start
  • 运行源程序,得到如下结果:实验2 多个逻辑段的汇编源程序编写与调试

 左下角显示彩色“NUIST”字样。

  • 使用debug工具对程序进行调试,使用g命令一次性执行到程序返回前(即ine25执行之后、line27 执行之前):实验2 多个逻辑段的汇编源程序编写与调试

 

阅读源程序,从理论上分析源代码的功能,可以得出:

  • 源代码中19行:and al,0dfh命令,将任何数与0dfh(11011111)做与运算,将从高到低第3位置0,实现的是将小写字母的二进制表示转换成与之对应的大写字母二进制表示,即小写转换大写的功能。
  • 源代码第4行里5个字节单元的值控制字母的颜色,对其稍作修改
db 2,3,4,5,6
--> 改成:
db 5 dup(2)  或 db 5 dup(5)

重新汇编,链接,运行,观察结果:

改成 db 5 dup(2):绿色“NUIST”实验2 多个逻辑段的汇编源程序编写与调试

  改成 db 5 dup(5):品红色“NUIST”实验2 多个逻辑段的汇编源程序编写与调试

实验任务六

已知8086汇编源程序task6.asm代码片段如下:

 1 assume cs:code, ds:data
 2 
 3 data segment
 4 db 'Pink Floyd      '
 5 db 'JOAN Baez       '
 6 db 'NEIL Young      '
 7 db 'Joan Lennon     '
 8 data ends
 9 
10 code segment
11 start:
12     ; xxx
13 mov ah, 4ch
14 int 21h
15 code ends
16 end start
  • 补全程序,实现将data段中的每行第一个单词从大写->小写,代码如下:
 1 code segment
 2 start:
 3 mov ax,data
 4 mov ds,ax
 5 mov cx,4
 6 mov bx,0
 7 s:  
 8 mov dx,cx
 9 mov cx,4
10 mov si,0
11     s0:
12         mov al,ds:[bx+si]
13         or al,00100000B
14         mov ds:[bx+si],al
15         inc si
16     loop s0
17 add bx,16
18 mov cx,dx
19 loop s
20 
21 mov ah, 4ch
22 int 21h
23 code ends
  • 补全并测试运行程序,用d命令查看data段对应的内存空间:每行第一个单词已经转换为小写。实验2 多个逻辑段的汇编源程序编写与调试

 

 实验任务七

问题场景描述:Power idea公司1975年-1979年的基本情况如下:

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

 程序task7.asm的逻辑段data中(line4-6),已经定义好了这些数据。task7.asm如下:

 1 assume cs:code, ds:data, es:table
 2 
 3 data segment
 4     db '1975', '1976', '1977', '1978', '1979'
 5     dw    16,   22,   382, 1356, 2390
 6     dw  3, 7, 9, 13, 28
 7 data ends
 8 
 9 table segment
10     db 5 dup( 16 dup(' ') )  ;
11 table ends
12 
13 code segment
14 start:
15     
16     mov ah,4ch
17     int 21h
18 code ends
19 end start
  • 补全程序,实现题目要求:把年份、收入、雇员人数、人均收入以结构化的方式写入table中,表格中每行数据,在逻辑段 table中占16个字节,各项数据占据字节大小分配如下。期中,数据之间用空格间隔。

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

 

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
col1:
    mov ax, [bx]
    mov es:[bp], ax
    mov ax, [bx+2]
    mov es:[bp+2], ax
    add bx, 4
    add bp, 10h
    loop col1

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

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

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

    mov ah, 4ch
    int 21h
code ends
end start
  • 查看table段的原始信息:实验2 多个逻辑段的汇编源程序编写与调试
  •  使用d命令查看table段对应的内存空间,确认信息已经按要求写入到指定内存:实验2 多个逻辑段的汇编源程序编写与调试

 

上一篇:asm-examples


下一篇:ASM的文件管理深入解析(内含开源的ASM文件挖掘研究版程序)