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

一、实验目的

1. 理解和掌握将数据、代码、栈放入不同逻辑段的程序的编写和调试
2. 理解具有多个段的汇编源程序对应的目标程序执行时,内存分配方式
3. 掌握大小写字符的转换方法、数字字符和数值之间的转换方法
4. 理解并掌握各种寻址方式的灵活应用
5. 掌握汇编指令loop, and, or,div, mul的用法

二、实验准备

复习教材chapter 6-8章。
chapter 6 包含多个段的程序
chapter 7 更灵活的定位内存地址的方法
chapter 8 数据处理的两个基本问题
 

三、实验内容

实验任务1

使用任意文本编辑器,录入汇编源程序task1.asm。
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

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

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

 

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

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

答:猜测高位字符代表显存,低位输出字符的颜色。

实验任务2

编写程序,在屏幕上以十进制整数形式打印输出这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 cx,5 
        mov di,0

s:      mov al,ds:[di]        
        mov bl,10       
        mov ah,0        
        div bl     
        mov ds:[di+10],al  
        mov ds:[di+11],ah
     
        mov ah,2    
        mov dl,ds:[di+10]
        add dl,30h    
        int 21h 
        
        mov ah,2        
        mov dl,ds:[di+11]
        add dl,30h        
        int 21h  
  
        mov ah,2 
        mov dl," "
        int 21h 
        inc di        
        loop s        

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

经过编译,链接,执行得到如下结果:

 实验任务3:

 将下面的程序编译、链接、用debug加载、跟踪,然后回答问题:   

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

对程序进行编译、连接:

debug调试,用u命令进行反汇编,用g命令执行程序到程序退出前:

问题一:CPU执行程序,程序返回前,data段中的数据为多少?

data段中的数据为:23 01 56 04 89 07 BC 0A EF 0D ED 0F BA 0C 87 09

问题二:CPU执行程序,程序返回前,cs=076CH 、ss=076BH 、ds=076AH 。

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

实验任务4

将下面的程序编译、连接,用Debug加载、跟踪,然后回答问题。

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

对程序进行编译、连接:

debug调试,用u命令进行反汇编,用g命令执行程序到程序退出前,并查看data段中数据:

问题一:CPU执行程序,程序返回前,data段中的数据为多少?

             data段中的数据为:23 01 56 04 00 00 00 00 00 00 00 00 00 00 00 00 

问题二:CPU执行程序,程序返回前,cs=076ch,ss=076bh,ds=076ah.

问题三:data段段地址X-2,stack段地址X-1.

问题四:对于如下定义的段

name segment
...
name ends

  如果段中的数据占N个字节,那么程序加载后,该段实际占有空间为:(int(N/16)+1)*16

实验任务5

将下面的程序编译、连接,用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

反汇编调试,用g命令执行到程序返回前的调试:

问题一:CPU执行程序,程序返回前,data段中的数据为多少?

data段中的数据为:23 01 56 04 00 00 00 00 00 00 00 00 00 00 00 00 

问题二:CPU执行程序,程序返回前,cs=076AH 、ss=076EH 、ds=076DH 。

问题三:设程序加载后,code段的段地址为X,则data段的段地址为X+3,stack段的段地址为X+4。

实验任务6

如果将(1)、(2)、(3)题中最后一条伪指令“end start”改为“end”(也就是说,不指明程序的入口),则哪个程序仍然可以正确执行?请说明原因。

答:第(3)题程序仍可以正确执行(task5.exe)。因为如果不指明入口位置,则程序会按顺序从所分配的空间开始执行,CPU无法自动识别哪些是指令哪些是数据。由于第(3)题是汇编指令段开头,按顺序能够正确执行。

实验任务7

程序如下,编写code段中的代码,将a段和b段中的数据依次相加,将结果存到c段中。

assume cs:code
a segment
  db 1,2,3,4,5,6,7,8
a ends

b segment
  db 1,2,3,4,5,6,7,8
b ends

c1 segment   ; 在集成软件环境中,请将此处的段名称由c→改为c1或其他名称?
  db 8 dup(0)
c1 ends

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

s:   mov si,a
     mov ds,si
     mov al,ds:[bx]

     mov si,b
     mov ds,si
     add al,ds:[bx]

     mov si,c1 
     mov ds,si
     mov ds:[bx],al
     inc bx
     loop s

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

对程序进行编译、连接:

用debug进行调试,用u命令进行反汇编:

在debug环境中,执行到程序返回前,查看逻辑段c的数据的截图

实验任务8

程序如下,编写code段中的代码,用push指令将a段中的前8个字型数据,逆序存储到b段中。

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 bx,0       
         mov cx,8       
         mov si,a       
         mov ds,si
s:       push ds:[bx]       
         add bx,2      
         loop s      
         mov bx,0 
         mov si,b 
         mov cx,8  
         mov ds,si
s1:     pop ds:[bx] 
         add bx,2
         loop s1 
         mov ah,4ch 
         int 21h
code ends
end start

对程序进行编译、连接:

用debug进行调试,用u命令进行反汇编:

用g命令执行到程序返回前并查看:

posted @ 2020-11-26 22:22  无问夕故  阅读(109)  评论(1编辑  收藏  举报