实验3 多个段的汇编源程序编写与调试
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 segments
db 23, 50, 66, 71, 35
data ends
编写程序,在屏幕上以十进制整数形式打印输出这5个两位数。
利用除法指令div,计算出每个数位上的数值:
利用数值和数字字符之间ascII码的关系,把各位上的数值加上48,得出相应字符
利用系统功能调用int 21h中的2号子功能,输出单个字符 字符之间用 mov dl,32 int 21h 的方式输出空格
mov dl,xx int 21h

3.实验任务3
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
debug加载跟踪


①CPU执行程序,程序返回前,data段中的数据为多少?
8个字型数据占16个字节,由d命令查看,发现data段中的数据为16字节,data段中的数据为:0123 0456 0789 0ABC 0DEF 0FED 0CBA 0987

②CPU执行程序,程序返回前,cs=076CH,ss=076BH,ds=076AH。

③设程序加载后,code段的段地址为X,则data段的段地址为X-2,stack段的段地址为X-1。
076B-076A=1 076C-076A=2
data段定义了8个字(16个字节)数据的空间,stack段同样定义了16个字节的空间,而且程序一次最少分配16个字节的空间,所以data段与stack段相差10h个字节,stack段与code段相差10H个字节,data段与code段相差20H个字节。又因为段地址*10H+偏移地址=物理地址所以答案得出。
4.实验任务4
将下面的程序编译、链接、用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段中的数据为多少?
2个字型数据占4个字节,由d命令查看,发现data段中的数据为4字节,data段中的数据为0123 0456

②CPU执行程序,程序返回前,由运行结果可以看出cs=076CH,ss=076BH,ds=076AH。

③设程序加载后,code段的段地址为X,则data段的段地址为X-2,stack段的段地址为X-1。
④如果段中的数据占N个字节,则程序加载后,该段实际占有的空间为(floor(N/16)+1)*16。
最少占用16个字节且占用的字节数是16的倍数。
测试:
data segment dw 0123h,0456h,0789h,0abch data ends stack segment dw 1,1,1,1,0,0,0,0,0 stack ends
cx可知整个程序占52H个字节 u命令反汇编得到data段的代码,占用22H个字节可知剩下的空间为30H。data段占10H stack段占20H


5.实验任务5
将下面的程序编译、链接、用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
①CPU执行程序,程序返回前,data段中的数据为多少?
数据为0123 0456


②CPU执行程序,程序返回前,由运行结果可以看出cs=076AH,ss=076EH,ds=076DH。
③设程序加载后,code段的段地址为X,则data段的段地址为X+3,stack段的段地址为X+4。
6.实验任务6
如果将前三题中的最后一条伪指令“end start”改为“end”(也就是说,不指明程序的入口),则哪个程序仍然可以正确执行?请说明原因。
只有(3)的程序中可以正确执行因为(3)的data段和stack段是定义在code段后面的,在反汇编成源代码时code段代码依然可以正确执行。
另外两题的code段代码都定义在data和stack段后面,会先将data和stack段的数据反汇编成要执行的code代码,所以程序不能正确执行。
7.实验任务7
编写code段中的代码,将a段和b段中的数据依次相加,将结果存到c1段中。
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 bx, 0
mov cx, 8
s:
mov si, a
mov ds, si
mov al, ds:[bx] ;将a段中的数据存入al
mov si, b
mov ds, si
add al, ds:[bx] ;将a段与b段的数据相加
mov si, c1
mov ds, si
mov ds:[bx], al ;将结果存入c1段中
inc bx
loop s
mov ax, 4c00h
int 21h
code ends
end start
执行前a段内容

b段内容

c段内容:

执行后:

8.实验任务8
编写code段中的代码,用push指令将a段中的前8个字型数据,逆序存储到b段中。
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 bx, 0
mov cx, 8
mov si, a
mov ds, si
s: push ds:[bx] ;先将a段的数据压入栈中
add bx, 2
loop s
mov bx, 0
mov cx, 8
mov si, b
mov ds, si
s1: pop ds:[bx] ;出栈存入b段内存
add bx, 2
loop s1
mov ax, 4c00h
int 21h
code ends
end start
执行前查看b段内容:

执行后:

1. 通过本次实验理解了段的含义以及空间分配:在程序中段名代表一个地址这个地址指向存储该段数据的内存空间。
一个段的空间大小为16字节的整数倍,即使一段中定义使用的字节数不足16个字节也占用至少16个字节的空间。
对于数据和代码的存放应当存放在不同定义的逻辑段中放置代码混乱,且代码段应当有start 和end start 放置将数据段当做代码段执行。
2. div指令用法:若除数为8位,被除数为16位则被除数默认在ax中存放,运算结果:al存储商,ah存储余数。

浙公网安备 33010602011771号