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

目录

实验内容

实验任务1

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

 1 assume cs:code, ds:data
 2 data segment
 3 db 'Nuist'
 4 db 5 dup(2)
 5 data ends
 6 code segment
 7 start:
 8 mov ax, data
 9 mov ds, ax
10 mov ax, 0b800H
11 mov es, ax
12 mov cx, 5
13 mov si, 0
14 mov di, 0f00h
15 s: mov al, [si] 
16 and al, 0dfh     //and命令,是逻辑与,将al与0dfh,即为1101 1111进行按位与操作。
17 mov es:[di], al
18 mov al, [5+si]
19 mov es:[di+1], al
20 inc si
21 add di, 2
22 loop s
23 mov ah, 4ch
24 int 21h
25 code ends
26 end start

  使用-g命令执行程序,得到下图 

 出现了绿色的NUIST字样。

将line4中的五个字节,重新汇编,连接。

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

运行过后得到如下图:

 可以发现,绿色的NUIST变成了彩色,可以得到猜测,dup(2)控制的是字体的颜色。

 

 

实验任务2

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

1 data segments
2 db 23, 50, 66, 71, 35
3 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

s1:    mov ah,0
    mov al,ds:[di]
    mov bl,10
    div bl                  //拆分字符串
    mov ds:[10+di],al
    mov ds:[11+di],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 s1

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

经过汇编,连接得到exe文件,执行可以得到:

 可以看到,首先使用div指令拆分字符串,随后利用地址以及int 21h命令将其输出。

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

经过汇编、连接得到task3.exe可执行文件,反汇编

得到代码:

 1.查看dw中的元素:

 使用 -g 1d命令执行程序,到打印之前,得到寄存器内容如下:

 2.可发现,CS = 076CH,SS = 076BH, DS = 076AH

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

 

 

实验任务4

实验源码task4.asm:

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

经过汇编、连接后得到task4.exe可执行文件,进行反汇编

 查看data中的数据:

 发现其中数据为:1023H,0456H, 0000H, 0000H, 0000H, 0000H, 0000H, 0000H。

 使用 -g 1d执行程序,得到 CS=076CH,SS=076BH,DS=076AH

查看DS中的数据发现没有改变。

 因此:

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

2.CPU执行程序,程序返回前,cs=076ch,ss=076bh,ds=076ah

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

4.对如下定义的段:

name segment
···
name ends

如果段中的数据占 N 个字节,不是16字节的整数倍,则会补整,则程序加载后,

该段实际占用的空间为:ceil(N+15)/16)*16,ceil()表示向上取整

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

 反汇编得到代码如下:

 运行到076A:000D之前:

 查看数据段中的数据:

 可以发现数据如下:0123H, 0456H, 0000H, 0000H, 0000H, 0000H, 0000H, 0000H.

执行命令,得到CS=076AH,SS=076EH,DS=076DH 

在查看数据段中的内容,发现并没有变化:

由上可知,

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

2.CPU执行程序,程序返回前,cs=076ah,ss=076Eh,ds=076dh

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

实验任务6

 只有教材中实验5的3 的程序能够正常运行。因为如果将 end start 改为 end,那么不指明入口,会默认从 076A:0 开始执行,

前两个的076A:0开始的地址存放的都是数据而不是指令,因此会报错

第三个是先存储的指令随后存储的数据,因而可以运行。

实验任务7

程序源码见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 si,0
        mov cx,9
s:      mov ax,0
        mov al,[si]
        add al,[si+16]
        mov [si+32],al
        inc si
        loop s
        mov ah,4ch
        int 21h
       
code ends
end start
复制代码

经过汇编,连接得到task7.exe可执行文件。

因为a,b,c段的长度都是16,所以就直接通过加偏移量16 32来进行访问

使用-g 19执行,查看a,b,c的数据,看到最后一行的数据是由前面两行相加得到的,满足要求。

实验任务8

源码见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,b
        mov ss,ax
        mov sp,10h
        mov ax,a
        mov ds,ax
        mov si,0
        mov cx,9
s:      push ds:[si]
        add si,2
        loop s
        mov ah,4ch
        int 21h
code ends
end start

反汇编后

 

 可以发现,代码在001AH处调用int 21,使用

-g 001A命令执行程序。

 

从上图中查看的结果看出结果满足实验要求,实现了逆序存储。

posted @ 2020-11-27 12:18  艾瑞克Aric  阅读(127)  评论(2)    收藏  举报