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

目录


实验内容

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

理论分析:
程序首先将Data段中的数据的小写字母转化为大写字母,同时将颜色转变为绿色然后移动数据到显卡内存上使之显示出来。
实验步骤:

1
task1.asm执行结果
1
task1.exe反汇编
1
data段数据
1
修改数据之后的运行结果
根据修改之后的结果推测,修改的数据是用来控制字体颜色的。

实验任务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 dh,0ah

	mov di,0
	mov cx,5
s:	mov al,[di]
	mov ah,00h
	div dh
	add al,30h		;数字与字符相差48,即16进制30h
	add ah,30h
	mov bx,ax
	inc si

	mov ah,2
	mov dl,bl
	int 21h
	mov dl,bh
	int 21h
	loop s
 
	mov ah,4ch
	int 21h
code ends
end start

实验步骤;

1
task2.asm执行结果

实验任务3
教材「实验5 编写、调试具有多个段的程序」(1)
将下面的程序编译、连接,用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

回答问题:

  • CPU执行程序,程序返回前,data段中的数据为多少?
    答:data段中数据为23 01 56 04 89 07 BC 0A EF 0D ED 0F BA 0C 87 09
  • CPU执行程序,程序返回前,cs=?, ss=?, ds=?
    答:cs:076C, ss:0769, ds:075A
  • 设程序加载之后, code段的段地址为X,则data段的段地址为?,stack段的段地址为?
    答:data段的段地址为X-1,stack段的段地址为X-2
实验步骤:
1
debug中查看task3.asm
1
反汇编查看data段数据和stack段数据
1
调试到程序返回前

实验任务4
教材「实验5 编写、调试具有多个段的程序」(2)
将下面的程序编译、连接,用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

回答问题:

  • CPU执行程序,程序返回前,data段中的数据为多少?
    答:data段中数据为23 01 56 04
  • CPU执行程序,程序返回前,cs=?, ss=?, ds=?
    答:cs:076C, ss:0769, ds:075A
  • 设程序加载之后, code段的段地址为X,则data段的段地址为?,stack段的段地址为?
    答:data段的段地址为X-1,stack段的段地址为X-2
  • 对于如下定义的段:
    name segment
    ...
    name ends

    如果段中数据占N个字节,则程序加载之后,该段实际占有的空间为?
    答:该段实际占有的空间为⌈N/16⌉*16字节
实验步骤:
1
debug中查看task4.asm
1
反汇编查看data段数据和stack段数据
1
调试到程序返回前

实验任务5
教材「实验5 编写、调试具有多个段的程序」(3)
将下面的程序编译、连接,用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

回答问题:

  • CPU执行程序,程序返回前,data段中的数据为多少?
    答:data段中数据为23 01 56 04 89 07 BC 0A EF 0D ED 0F BA 0C 87 09
  • CPU执行程序,程序返回前,cs=?, ss=?, ds=?
    答:cs:076A, ss:0769, ds:075A
  • 设程序加载之后, code段的段地址为X,则data段的段地址为?,stack段的段地址为?
    答:data段的段地址为X-1,stack段的段地址为X-2
实验步骤:
1
debug中查看task5.asm
1
反汇编查看data段数据和stack段数据
1
调试到程序返回前
在调试过程中,发现在代码中data段和stack段位置的不同会影响这两个段的数据存储的相对位置。如果data段和stack段在code段前面,那么实际存储的过程中段地址stack=code-1,data=code-2; 如果data段和stack段在code段后面,那么实际存储的过程中段地址stack=code+代码长度+1,data=code+代码长度+2;

实验任务6
教材「实验5 编写、调试具有多个段的程序」(4)
如果将(1)、(2)、(3)题中的最后一条伪指令”end start“改为”end“也就是说不知名程序的入口),则哪个程序任然可以正确执行?请说明理由。
(3)题中的程序可以正确执行,因为end start是指定程序的入口,如果删掉start,那么机器会将代码一开始作为程序的入口,但是(1)(2)中代码开始定义的是data段和stack段,只有(3)
将code段放在了开头,所以能够正确执行。

实验任务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 ax,a
	mov ds,ax
	mov bx,0
	mov cx,8

s:	mov ax,ds:[bx]
	add ax,ds:[bx+16]
	mov ds:[bx+32],ax
	inc bx
	loop s
	mov ah,4ch
	int 21h
code ends
end start
1
查看逻辑段c中的数据

实验任务8
教材「实验5 编写、调试具有多个段的程序」(6)
程序如下:编写code段中的代码,用push指令将a段中前8个字型数据逆序存储到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 cx,8
s:	push ds:[bx]
	add bx,2
	loop s

	mov ax,b
	mov ds,ax
	mov bx,0

	mov cx,8
qs:	pop ds:[bx]
	add bx,2
	loop qs

	mov ah,4ch
	int 21h  
code ends
end start
1
查看逻辑段c中的数据

实验总结

  • 1.学习到了单个字符打印方式,利用int 21h的二号子功能,可以实现打印字符。
  • 2.每一个数据段的空间只能是16的倍数,可以通过这个计算数据空间,结合cx的值,减去mov ah,4c00h占用的两个字节进行精确的反汇编。 同时每个单独声明的数据段占据不同16倍数字节。
  • 3.数据段开辟的顺序与在代码中声明的顺序有关,先声明的在前面,后声明的在后面。“end start”语句的作用是确定程序运行的入口,如果 省略start会导致程序入口被机器确定在开头,而后者往往是数据段的位置,导致程序运行出错。
  • 4.栈具有先进后出的特点,可以用来顺序或者逆序存储数据。
posted @ 2020-11-24 19:10  qylh  阅读(176)  评论(2编辑  收藏  举报