实验3 多个段的汇编源程序编写与调试

1. 实验任务1

 

    使用任意一款文本编辑器,编写8086汇编源程序ex1.asm。源代码如下:

;ex1.asm
assume cs:code
code segment
    mov ax, 0b810h
    mov ds, ax
    mov byte ptr ds:[0], 1
    mov byte ptr ds:[1], 1
    mov byte ptr ds:[2], 2
    mov byte ptr ds:[3], 2
    mov byte ptr ds:[4], 3
    mov byte ptr ds:[5], 3
    mov byte ptr ds:[6], 4
    mov byte ptr ds:[7], 4
    mov ah, 4ch
    int 21h
code ends
end

阅读源程序,从理论上分析源代码的功能,尤其是line15-25,循环实现的功能是什么,逐行理解每条指 令的功能。

  使用masm、link对task1.asm进行汇编、链接,得到可执行文件task1.exe,运行并观  察结果。

  使用debug工具对程序进行调试,执行到程序返回前,即line27之前,观察结果。

 

  修改line4里5个字节单元的值,重新汇编、链接、运行,观察结果。

db 5 dup(2)
--> 改成:
db 2,3,4,5,6

基于观察,分析、猜测这里的数值作用是什么。

 

 

 

 (1)首先向数据段的前10个字节输入数据,其中db 5 dup(2)表示5个重复的2(字节数据)。向附加段寄存器es输送显存地址(在内存地址结构中,B8000H~BFFFFH共32KB的空间,为80x25彩色字符模式的显示缓冲区。向这个地址空间写入数据,写入的内容将立即出现在显示器)。执行5次循环,循环的内容是:将数据段中的字符数据送往显存地址中,并执行add al,odfh(将小写转化为大写),mov al, [5+si],mov es:[di+1], al(为设置显示颜色的操作,将2送往显存中存储对应字符地址的下一个地址,实现控制颜色)。

 

(2)db 2,3,4,5,6即设置颜色的值为不同颜色。

2. 实验任务2

 

已知数据段data中定义字节数据如下:

data segments
db 23, 50, 66, 71, 35
data ends

编写程序,在屏幕上以十进制整数形式打印输出这5个两位数。

assume cs:code, ds:data
data segment
    db 23,50,66,71,35
data ends
code segment
start:
    mov ax,data
    mov ds,ax
    mov di,0
    mov cx,5
s:  mov ah,0       
    mov al,ds:[di]      
    mov bl,10
    div bl        
    mov ds:[di+10],al  
    mov ds:[di+11],ah  
    mov ah,2      
    mov dl,ds:[10+di]    
    add dl,30h
    int 21h       
    mov ah,2      
    mov dl,ds:[11+di]  
    add dl,30h
    int 21h          
    mov ah,2
    mov dl," "
    int 21h
    inc di            
    loop s
    mov ax,4c00h    
    int 21h
code ends
end start

 

 

 3. 实验任务3

教材「实验5 编写、调试具有多个段的程序」(1) 程序源码见task3.asm

assume cs:code, ds:data, ss:stack
data segment
  dw 0123h, 0456h, 0789h, 0abch, 0defh, 0fedh, 0cbah, 0987h
data ends
 
stack segment
  dw 0, 0, 0, 0, 0, 0, 0, 0
stack ends
 
code segment
start:  mov ax,stack
        mov ss, ax
        mov sp,16
         
        mov ax, data
        mov ds, ax
         
        push ds:[0]
        push ds:[2]
        pop ds:[2]
        pop ds:[0]
         
        mov ax,4c00h
        int 21h
 
code ends
end start

 

 

 

 1、CPU执行程序,程序返回前,data段中数据为多少?

0123,0456,0789,0abc,0def,0fed,0cba,0987

2、CPU执行程序,程序返回前,cs=076c,ss=0769,ds=075a

3、设程序加载后,code段的段地址为X,则data段的段地址为x-2,stack段的段地址为x-1

4. 实验任务4

 

教材「实验5 编写、调试具有多个段的程序」(2) 程序源码见task4.asm。

assume cs:code, ds:data, ss:stack
data segment
  dw 0123h, 0456h
data ends
 
stack segment
  dw 0, 0
stack ends
 
code segment
start:  mov ax,stack
        mov ss, ax
        mov sp,16
         
        mov ax, data
        mov ds, ax
         
        push ds:[0]
        push ds:[2]
        pop ds:[2]
        pop ds:[0]
         
        mov ax,4c00h
        int 21h
 
code ends
end start

 

 

 

 21由42-十进制(16+16)=22得出

data段中的数据为:0123h, 0456h

CPU执行程序,程序返回前,cs=076C、ss=076B、ds=076A

设程序加载后,code段的段地址为X,则data段的段地址为X-2,stack段的段地址为X-1

如果段中的数据占N个字节,则程序加载后,该段实际占有的空间为:(N/16)*16   注意: (N/16)向上取整。

5. 实验任务5

此部分书写内容: 附上源代码文件task5.asm 回答教材中①②③三个问题。 附上回答②时反汇编调试截图,即:在debug中,执行到程序返回前的调试截图。

assume cs:code, ds:data, ss:stack
 
code segment
start:  mov ax,stack
        mov ss, ax
        mov sp,16
         
        mov ax, data
        mov ds, ax
         
        push ds:[0]
        push ds:[2]
        pop ds:[2]
        pop ds:[0]
         
        mov ax,4c00h
        int 21h
 
code ends
data segment
  dw 0123h, 0456h
data ends
 
stack segment
  dw 0,0
stack ends
end start

 

 1、CPU执行程序,程序返回前,data段中的数据为:0123h, 0456h

2、CPU执行程序,程序返回前,cs=076A,ss=076E,ds=076D

 

3、设程序加载后,code段的段地址为X,则data段的段地址为X+3,stack段的段地址为X+4

6. 实验任务6

此部分书写内容: 回答教材中提出的问题,并按要求说明原因。

实验任务五可以正常执行。如果不指名程序入口,实验任务三和四代码的前几行数据段将被当做代码来执行,

而实验任务五的代码把数据段和栈段的内容放在代码段的后面,所以不会影响程序的正常执行。

7. 实验任务7

此部分书写内容: 附上完整源代码文件task7.asm

附上在debug环境中,执行到程序返回前,查看逻辑段c的数据的截图,以此验证所编写的程序正 确实现了题目要求。

1
assume cs:code<br>a segment<br>  db 1,2,3,4,5,6,7,8<br>a ends<br><br>b segment<br>  db 1,2,3,4,5,6,7,8<br>b ends<br><br>c segment   <br>  db 8 dup(0)<br>c ends<br><br>code segment<br>start:<br>       mov ax,a<br>       mov ds,ax<br>       mov si,0<br>       mov cx,8<br>       s:mov al,ds:[si]<br>       add al,ds:[si+16]<br>       mov ds:[si+32],al<br>       inc si<br>       loop s<br>       mov ax,4c00h<br>       int 21h<br>code ends<br>end start

 

 指令长度为4BH ,数据段共占用30H个字节,故 u 0 1a ,g命令执行到编号为16的指令之前,调用d命令查看c处的内存单元内容 c的起始地址为 ds:20 共对8个字节的数字进行加法,故查看到27截至。

8. 实验任务8

此部分书写内容: 附上完整源代码文件task8.asm 附上在debug环境中,执行到程序返回前,查看逻辑段c的数据的截图,以此验证所编写的程序正 确实现了题目要求。

assume cs:code
a segment
    dw 1,2,3,4,5,6,7,8,9,0ah,0bh,0ch,0dh,0eh,0fh,0ffh
a ends
 
b segment
    dw 8 dup(0)
b ends
 
code segment
start: 
    mov ax,a
    mov ds,ax
    mov bx,0
    mov ax,b
    mov ss,ax
    mov sp,16
    mov cx,8
    s:push [bx]
    add bx,2
    loop s
    mov ax,4c00h
    int 21h
code ends
end start

 

 指令总长度为4FH,其中30H为数据段和栈段的内容,故u 0 1E

调用d命令查询cpu执行后栈段中的内容如图

 

1. 实验任务1

使用任意文本编辑器,录入汇编源程序task1.asm。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
assume cs:code, ds:data
data segment
db 'Nuist'
db 5 dup(2)
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

阅读源程序,从理论上分析源代码的功能,尤其是line15-25,循环实现的功能是什么,逐行理解每条指 令的功能。

  使用masm、link对task1.asm进行汇编、链接,得到可执行文件task1.exe,运行并观  察结果。

  使用debug工具对程序进行调试,执行到程序返回前,即line27之前,观察结果。

  修改line4里5个字节单元的值,重新汇编、链接、运行,观察结果。

1
2
3
db 5 dup(2)
--> 改成:
db 2,3,4,5,6

 基于观察,分析、猜测这里的数值作用是什么。

 

 

 

 (1)首先向数据段的前10个字节输入数据,其中db 5 dup(2)表示5个重复的2(字节数据)。向附加段寄存器es输送显存地址(在内存地址结构中,B8000H~BFFFFH共32KB的空间,为80x25彩色字符模式的显示缓冲区。向这个地址空间写入数据,写入的内容将立即出现在显示器)。执行5次循环,循环的内容是:将数据段中的字符数据送往显存地址中,并执行add al,odfh(将小写转化为大写),mov al, [5+si],mov es:[di+1], al(为设置显示颜色的操作,将2送往显存中存储对应字符地址的下一个地址,实现控制颜色)。

(2)db 2,3,4,5,6即设置颜色的值为不同颜色。

2. 实验任务2

已知数据段data中定义字节数据如下:

1
2
3
data segments
db 23, 50, 66, 71, 35
data ends

 编写程序,在屏幕上以十进制整数形式打印输出这5个两位数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
assume cs:code, ds:data
data segment
    db 23,50,66,71,35
data ends
code segment
start:
    mov ax,data
    mov ds,ax
    mov di,0
    mov cx,5
s:  mov ah,0        //*将字节数据存入ax寄存器中,因为ax存储2个字节,所以
    mov al,ds:[di]      ah中存0*//
    mov bl,10
    div bl         //ax中数据除以10,余数存在ah,商存在al
    mov ds:[di+10],al  //将商的内容存入数据段中,(取可用的内存单元即可)
    mov ds:[di+11],ah  //将商的内容存入数据段中,(取可用的内存单元即可)
    mov ah,2       //*
    mov dl,ds:[10+di]     显示商
    add dl,30h
    int 21h       *//
    mov ah,2       //*
    mov dl,ds:[11+di]   显示余数
    add dl,30h
    int 21h            *//
    mov ah,2
    mov dl," "
    int 21h
    inc di             //di自增1,用于读取下一位置处的字节数据
    loop s
    mov ax,4c00h   
    int 21h
code ends
end start

 

3. 实验任务3

教材「实验5 编写、调试具有多个段的程序」(1) 程序源码见task3.asm

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
assume cs:code, ds:data, ss:stack
data segment
  dw 0123h, 0456h, 0789h, 0abch, 0defh, 0fedh, 0cbah, 0987h
data ends
 
stack segment
  dw 0, 0, 0, 0, 0, 0, 0, 0
stack ends
 
code segment
start:  mov ax,stack
        mov ss, ax
        mov sp,16
         
        mov ax, data
        mov ds, ax
         
        push ds:[0]
        push ds:[2]
        pop ds:[2]
        pop ds:[0]
         
        mov ax,4c00h
        int 21h
 
code ends
end start

 

 

 

 

1、CPU执行程序,程序返回前,data段中数据为多少?

0123,0456,0789,0abc,0def,0fed,0cba,0987

2、CPU执行程序,程序返回前,cs=076c,ss=0769,ds=075a

3、设程序加载后,code段的段地址为X,则data段的段地址为x-2,stack段的段地址为x-1

4. 实验任务4

教材「实验5 编写、调试具有多个段的程序」(2) 程序源码见task4.asm。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
assume cs:code, ds:data, ss:stack
data segment
  dw 0123h, 0456h
data ends
 
stack segment
  dw 0, 0
stack ends
 
code segment
start:  mov ax,stack
        mov ss, ax
        mov sp,16
         
        mov ax, data
        mov ds, ax
         
        push ds:[0]
        push ds:[2]
        pop ds:[2]
        pop ds:[0]
         
        mov ax,4c00h
        int 21h
 
code ends
end start

 

 

21由42-十进制(16+16)=22得出

data段中的数据为:0123h, 0456h

CPU执行程序,程序返回前,cs=076C、ss=076B、ds=076A

设程序加载后,code段的段地址为X,则data段的段地址为X-2,stack段的段地址为X-1

如果段中的数据占N个字节,则程序加载后,该段实际占有的空间为:(N/16)*16   注意: (N/16)向上取整。

5. 实验任务5

此部分书写内容: 附上源代码文件task5.asm 回答教材中①②③三个问题。 附上回答②时反汇编调试截图,即:在debug中,执行到程序返回前的调试截图。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
assume cs:code, ds:data, ss:stack
 
code segment
start:  mov ax,stack
        mov ss, ax
        mov sp,16
         
        mov ax, data
        mov ds, ax
         
        push ds:[0]
        push ds:[2]
        pop ds:[2]
        pop ds:[0]
         
        mov ax,4c00h
        int 21h
 
code ends
data segment
  dw 0123h, 0456h
data ends
 
stack segment
  dw 0,0
stack ends
end start

 

 

1、CPU执行程序,程序返回前,data段中的数据为:0123h, 0456h

2、CPU执行程序,程序返回前,cs=076A,ss=076E,ds=076D

 

3、设程序加载后,code段的段地址为X,则data段的段地址为X+3,stack段的段地址为X+4

6. 实验任务6

此部分书写内容: 回答教材中提出的问题,并按要求说明原因。

实验任务五可以正常执行。如果不指名程序入口,实验任务三和四代码的前几行数据段将被当做代码来执行,

而实验任务五的代码把数据段和栈段的内容放在代码段的后面,所以不会影响程序的正常执行。

7. 实验任务7

此部分书写内容: 附上完整源代码文件task7.asm

附上在debug环境中,执行到程序返回前,查看逻辑段c的数据的截图,以此验证所编写的程序正 确实现了题目要求。

1
assume cs:code<br>a segment<br>  db 1,2,3,4,5,6,7,8<br>a ends<br><br>b segment<br>  db 1,2,3,4,5,6,7,8<br>b ends<br><br>c segment   <br>  db 8 dup(0)<br>c ends<br><br>code segment<br>start:<br>       mov ax,a<br>       mov ds,ax<br>       mov si,0<br>       mov cx,8<br>       s:mov al,ds:[si]<br>       add al,ds:[si+16]<br>       mov ds:[si+32],al<br>       inc si<br>       loop s<br>       mov ax,4c00h<br>       int 21h<br>code ends<br>end start

 

 

 指令长度为4BH ,数据段共占用30H个字节,故 u 0 1a ,g命令执行到编号为16的指令之前,调用d命令查看c处的内存单元内容 c的起始地址为 ds:20 共对8个字节的数字进行加法,故查看到27截至。

8. 实验任务8

此部分书写内容: 附上完整源代码文件task8.asm 附上在debug环境中,执行到程序返回前,查看逻辑段c的数据的截图,以此验证所编写的程序正 确实现了题目要求。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
assume cs:code
a segment
    dw 1,2,3,4,5,6,7,8,9,0ah,0bh,0ch,0dh,0eh,0fh,0ffh
a ends
 
b segment
    dw 8 dup(0)
b ends
 
code segment
start:
    mov ax,a
    mov ds,ax
    mov bx,0
    mov ax,b
    mov ss,ax
    mov sp,16
    mov cx,8
    s:push [bx]
    add bx,2
    loop s
    mov ax,4c00h
    int 21h
code ends
end start

 

 

指令总长度为4FH,其中30H为数据段和栈段的内容,故u 0 1E

调用d命令查询cpu执行后栈段中的内容如图

posted @ 2020-12-05 00:47  dawei99  阅读(140)  评论(0)    收藏  举报