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段中的数据的小写字母转化为大写字母,同时将颜色转变为绿色然后移动数据到显卡内存上使之显示出来。
实验步骤:
实验任务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
实验步骤;
实验任务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
实验任务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字节
实验任务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
实验任务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
实验任务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.学习到了单个字符打印方式,利用int 21h的二号子功能,可以实现打印字符。
- 2.每一个数据段的空间只能是16的倍数,可以通过这个计算数据空间,结合cx的值,减去mov ah,4c00h占用的两个字节进行精确的反汇编。 同时每个单独声明的数据段占据不同16倍数字节。
- 3.数据段开辟的顺序与在代码中声明的顺序有关,先声明的在前面,后声明的在后面。“end start”语句的作用是确定程序运行的入口,如果 省略start会导致程序入口被机器确定在开头,而后者往往是数据段的位置,导致程序运行出错。
- 4.栈具有先进后出的特点,可以用来顺序或者逆序存储数据。