实验3 多个段的汇编源程序编写与调试
实验任务1
源代码
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
下图为运行结果&debug到程序返回前的截图

改变data段line4中的值后的结果

由两段代码及结果分析得到data段line4的字节数据用途是显示line段字符串的颜色
实验任务2
task2.asm源代码
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 ax, 0 mov si, 0 mov bl, 10 ;每次除以10,所以除数只需要8位,存储在bl中 mov cx, 5 ;需要做5次循环 s: mov al, ds:[si] div bl ;除以10 mov bh, ah ;ah中存储余数,因为寄存器冲突使用bh存储余数 mov dl, al ;al中存储商 add dl, 30h ;转换成ASCII码值,先输出商的值 mov ah, 2 int 21h mov dl, bh ;输出余数的值 add dl, 30h mov ah, 2 int 21h mov ax, 0 inc si loop s ;循环 mov ax,4c00h int 21h code ends end start
运行结果截图

实验任务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
根据理论分析,程序并没有改变data段中的数据,所以(1)的答案为:
23 01 56 04 89 07 bc 0a ef 0d ed 0f ba 0c 87 09
下图为反汇编查看data段中数据的截图,观察到的结果和理论分析一致
![]()
下图为在debug中执行到程序返回前的调试截图,得到(2)的答案:cs = 076c ss = 076b ds = 076a

data段定义了8个字即16个字节的空间,stack段定义了16个字节的空间,所以data段与stack段相差10h个字节,stack段又与cs段相差10h个字节。
(3)的答案为:data段的段地址为X-2,stack段的段地址为X-1
实验任务4
源代码:
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)根据理论分析,程序没有改变data段的数据,所以data段中的数据应该与源代码中data段的数据一致,即 23 01 56 04
(2)下图为在debug中执行到程序返回前的调试截图,由此得到答案:cs = 076c ss = 076b ds = 076a

(3)虽然data段只定义了4个字节的数据,但是根据段的定义,段的大小至少为16个字节,所以data段依然占用16个字节,stack段同理。所以data段的段地址为X-2,stack段的段地址为X-1
(4)因为一个段至少有16个字节,所以该段实际占有的空间为 [N/16]*16,其中N/16向上取整。
实验任务5
源代码
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
(1)data段的数据没有变化,数据为 01 23 56 04
(2)下图为debug中执行到程序返回前的调试截图,可以得到答案cs = 076a ss = 076e ds = 076d

(3)分析源代码,可以知道data段和stack段定义在code段之后,code段占用的字节空间为cx,所以data段的段地址为X+[cx/16]+1,ss段的段地址为X+[cx/16]+2,其中cx/16向上取整。
实验任务6
(3)题中的程序仍然可以正确执行。因为只有(3)的程序中的data段和stack段是定义在code段后面的,在反汇编成源代码时code段代码依然可以正确执行。另外两题的code段代码都定义在data和stack段后面,会将data和stack段的数据也反汇编成要执行的code代码,不能正确执行。
实验任务7
源代码
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
下图为逻辑段c1的数据的截图,验证程序正确实现了题目要求

实验任务8
源代码
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 s: mov si, a mov ds, si push ds:[bx] ;先将a段的数据压入栈中 add bx, 2 loop s mov bx, 0 s0: mov si, b mov ds, si pop ds:[bx] ;出栈存入b段内存 add bx, 2 loop s0 mov ax, 4c00h int 21h code ends end start
下图为逻辑段c的数据的截图,验证了所编写的程序正确实现了题目要求

实验结论
1. 通过本次实验更加明确了段的定义:一个段的大小至少为16个字节,段的起始地址应该为16的倍数,也就是说即使一段中定义的字节数不足16个字节也占用至少16个字节的空间。
2. 学会了div指令的用法:若除数为8位,被除数则为16位默认在ax中存放,al存储商,ah存储余数;若除数为16位,被除数则为32位在dx和ax中存放,ax存储商,dx存储余数;

浙公网安备 33010602011771号