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

一、实验目的

理解和掌握将数据、代码、栈放入不同逻辑段的程序的编写和调试

理解具有多个段的汇编源程序对应的目标程序执行时,内存分配方式

掌握大小写字符的转换方法、数字字符和数值之间的转换方法

理解并掌握各种寻址方式的灵活应用

掌握汇编指令loop, and, or,div, mul的用法

二、实验准备 复习教材chapter 6-8章。

chapter 6 包含多个段的程序

chapter 7 更灵活的定位内存地址的方法

chapter 8 数据处理的两个基本问题

三、实验内容

四、实验结论

实验任务1

 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] ;将data段的第si个字节送入al,即Nuist的某个字符
 and al, 0dfh ;通过and操作获取对应大写字母的ASCII码值
 mov es:[di], al ;将其送入对应的显示缓冲区:0b80:[di],以控制输出的字符
 mov al, [5+si] ;将data段的第si+5个字节送入al,该字节为控制字符的颜色属性
 mov es:[di+1], al;将控制字符的颜色属性的值传入显示缓冲区
 inc si ;si+1在下一次循环选则下一个字符
 add di, 2 ;di+2控制下一次送入显示缓冲区的位置
 loop s
 ​
 mov ah, 4ch
 int 21h
 code ends
 end start
 阅读源程序,从理论上分析源代码的功能,尤其是line15-25,循环实现的功能是什么,逐行理解每条指令的功能。
 答:分析如代码对应注释
 循环实现的是向对应显存区依次输入大写nuist的ASCII码值。
 使用masm、link对task1.asm进行汇编、链接,得到可执行文件task1.exe,运行并观察结果。

 

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

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

```asm

db 5 dup(2)  

--> 改成: 

db 2,3,4,5,6

1605707510663

修改后:

1605707552788

分析源代码中data段line4的字节数据的用途是?

答:控制ASCII码的字符属性(颜色属性)。

实验任务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     db 10 dup(0) data ends 
code segment
  start:
        mov ax, data
          mov ds, ax
          mov cx,5
          mov si,0
  s:
          mov ah, 0
          mov al, ds:[si]
          mov bl, 10
          div bl
          mov ds:[si+5],al
          mov ds:[si+6],ah
          mov ah, 2
          mov dl,ds:[si+5]
          add dl, 30h
          int 21h 
          mov ah, 2
          mov dl, ds:[si+6]
          add dl, 30h
          int 21h
          inc si
          mov ah, 2
          mov dl, 32 ;输出空格
          int 21h
          loop s
         
          mov ah, 4ch
            int 21h  
  code ends
  end start
附上运行结果截图
 ​
实验任务3
 ​
  ```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

回答教材中①②③三个问题。

①cpu执行程序返回前,data段中的数据为多少:data段不变。

1605705305104

②cpu执行程序返回前,cs=04B0h,ss=04AF,ds=04AEh。

debug时查看cx为42,data段和stack段共20h个字节,则汇编指令22个字节。

1605704351765

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

 

实验任务4 

   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
   

回答教材中①②③④四个问题。

①cpu执行程序返回前,data段中的数据为多少:data段不变

②cpu执行程序返回前,cs=04B0h,ss=04AFh,ds=04AEh。

1605705576347

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

④观察发现该实验与上一个实验分配的字节数一样,说明系统仍然分配了20h个字节空间。所以推测得到若段中的数据不足16个字节的倍数,系统会自动扩到16个字节为单位大的数据。 所以书上应该填:((N+15)/16)*16。

实验任务5

   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

回答教材中①②③三个问题。

①cpu执行程序返回前,data段中的数据为多少:data段不变。

②cpu执行程序返回前,cs=04AEh,ss=04B2h,ds=04B1h。

1605706524662

③设程序加载后,code段的段地址为x,则data段的段地址为x+3,stack段的段地址为x+4。

实验任务6

答:第三个程序可以正确执行,因为不指明程序入口后,前面俩个程序开头是数据段,不能直接执行指令,而第三个开头是代码即汇编指令段,可以正常执行。

实验任务7 

   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
  c segment  
    db 8 dup(0)
  c ends
  code segment
  start:
        mov ax,a
        mov ds,ax          
        mov ax,b
        mov es,ax          
        mov bx,0
        mov cx,8          
  s:
      mov dl, [bx]      
      add dl, es:[bx]    
      push ds             ;保护ds
      mov ax, c        
      mov ds, ax        
      mov [bx], dl       ;将dl(a和b相对应内存单元内容之和)写入c中
      pop ds             ;恢复ds
      inc bx            
      loop s
      mov ax,4c00h
      int 21h
  code ends
  end start
   

1605708231658

1605708231658

实验任务8

   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 0,0,0,0,0,0,0,0
   b ends
   code segment
   start:
      mov ax,a
      mov ds,ax      
      mov ax,b
      mov ss,ax      
      mov sp,16      
      mov bx,0
      mov cx,8        
   s:
      push ds:[bx]
      add bx,2
      loop s
      mov ax,4c00h
      int 21h
   code ends
   end start

1605708466669

 

五、实验总结 

(1)尝试了通过直接上传转化后的md文件发布,发现效果不是很好。

(2)加深了对于显存区域和ASCII码应用的理解

(3)巩固了不同方式访问内存地址的应用。

 
posted @ 2020-11-27 15:10  Defot  阅读(44)  评论(0)    收藏  举报