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

一、实验目的

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

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

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

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

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

 

二、实验准备

复习教材chapter 6-8章。

chapter 6 包含多个段的程序

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

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

 

三、实验内容

1. 实验任务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

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

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

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

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

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

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

 

对文件进行编译、连接

 

 debug后用u命令反汇编

 

 用g命令执行到程序返回前

 

 修改line4数据后

 

 line4的作用是控制字符的颜色属性

 

2. 实验任务2

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

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

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

提示: 1个两位数如何输出 思路如下:

 

 

具体处理步骤如下:

第1步,利用除法指令div,计算出每个数位上的数值。

第2步,利用数值和数字字符之间ascⅡ码的关系,把数值→数字字符

第3步,利用系统功能调用int 21h中的2号子功能,输出单个字

 

 int 21h中的2号子功能说明如下:

功能:输出单个字符

用法:

mov ah, 2
mov dl, ×× ; ××是待输出的字符,或其ASCⅡ码值
int 21h

5个两位数如何输出 利用loop指令,以及,灵活的寻址方式

 

 

 

 

ds的偏移地址设为[10+di]的目的是保证原有数据不被覆盖。

运行结果:

 

 

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段中数据为多少?

    data段数据为:0123h,0456h,0789h,0abch,0defh,0fdeh,0cbah,0987h

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

  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

 

 

  1. CPU执行程序,程序返回前,data段中数据为多少?           data段数据为0123h,0456h
  2. CPU执行程序,程序返回前,cs=076C、ss=076B、ds=076A
  3. 设程序加载后,code段的段地址为X,则data段的段地址为X-2,stack段的段地址为X-1
  4. 对于如下定义的段:
name segment

......

name ends

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

 

5. 实验任务5

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

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段中数据为多少?            data段数据为0123h,0456h
  2. CPU执行程序,程序返回前,cs=076A、ss=076E、ds=076D
  3. 设程序加载后,code段的段地址为X,则data段的段地址为X+3,stack段的段地址为X+4

6.实验任务6

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

(3)可以正常执行,(3) 题三开头为代码段,不需要指明入口,而(1)(2)不指明入口会将数据段当作指令执行

 

7. 实验任务7

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

 代码:

 

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 cx,8
      mov bx,0

s:    mov al,[bx]
      add al,[bx+10h]
      mov [bx+20h],al
      inc bx
      loop s

      mov ax,4c00h
      int 21h
code ends
end start

 

 

 

 

8. 实验任务8

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

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 ax,b
      mov ss,ax
      mov sp,16
      mov si,0

       mov cx,8

 s:   push ds:[si] 
      add  si,2
      loop s
      mov ax,4c00h
      int 21h
code ends
end start

 

posted @ 2020-11-26 19:29  敲代码了吗  阅读(120)  评论(3编辑  收藏  举报