实验3 多个段的汇编源程序编写与调试
实验任务1
源代码文件task1.asm
assume cs:code, ds:data data segment db 'Nuist' db 2,3,4,5,6 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
运行结果截图:
汇编、链接并运行task1.asm:

使用debug工具执行到程序返回前的结果:

修改line4里5个字节单元的值,重新汇编、链接、运行,观察结果:

基于观察,分析、猜测这里的data段line4数值作用是控制显示字符颜色的数值码。
实验任务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 cx, 5 mov si, 0 mov bl,10 mov ax,0b900H mov es,ax mov di,0f00H s: mov al, [si] mov ah,0 div bl add al,48 add ah,48 mov es:[di],al mov es:[di+1],ah mov ah, 2 mov dl, es:[di] int 21h mov ah, 2 mov dl, es:[di+1] int 21h mov ah, 2 mov dl, 32 int 21h inc si add di,2 loop s mov ah, 4ch int 21h code ends end start
运行结果截图:

实验任务3
源代码文件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
汇编、链接并执行程序的截图:

(1)CPU执行程序,程序返回前,data段中的数据为如下所示
反汇编的结果:

执行到程序退出前,用d命令查看data段的数据:

(2)CPU执行程序,程序返回前,cs=076C、ss=076B、ds=076A
执行到程序返回前的各个寄存器的数据:

(3)设程序加载后,code段的段地址为X,则data段的段地址为X-2,stack段的段地址为X-1
单步调试查看各个段寄存器存储的数据:

实验任务4
源代码文件task4.asm:
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)CPU执行程序,程序返回前,data段中的数据为如下所示
反汇编,运行到程序返回前,用d命令查看data段中的数据:

(2)CPU执行程序,程序返回前,cs=076C、ss=076B、ds=076A
执行到程序返回前各个段寄存器的数据:

(3)设程序加载后,code段的段地址为X,则data段的段地址为X-2,stack段的段地址为X-1
单步调试查看各个段寄存器存储的数据:

(4)对于如下定义的段:
name segment
...
name ends
如果段中的数据占N个字节,则程序加载后,该段实际占有的空间为16字节。
实验任务5
源代码文件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
汇编、链接并执行程序的截图:

(1)CPU执行程序,程序返回前,data段中的数据为如下所示
反汇编,运行到程序返回前,用d命令查看data段中的数据:

(2)CPU执行程序,程序返回前,cs=076A、ss=076E、ds=076D
执行到程序返回前各个段寄存器的数据:

(3)设程序加载后,code段的段地址为X,则data段的段地址为X+3,stack段的段地址为X+4
单步调试查看各个段寄存器存储的数据:

实验任务6
第(3)题的程序仍然可以正确执行,因为没有start指明程序的入口,程序将按照顺序执行,第(1)(2)题的程序数据段位于代码段的前面,所以数据段的数据会被当成指令被编译执行,虽然可能也会正确运行但会产生一些错误,但第(3)题数据段位于代码段的后面,按顺序执行不影响源程序的目的,并且会在代码段最后返回结果,不执行后面的数据段。
实验任务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 ax,c mov es,ax mov cx,8 mov di,0 s: mov dl,ds:[di] mov es:[di],dl inc di loop s mov ax,b mov ds,ax mov cx,8 mov di,0 s0: mov dl,es:[di] add dl,ds:[di] mov es:[di],dl inc di loop s0 mov ah,4ch int 21h code ends end start
汇编、链接并执行程序的截图:

使用debug查看当前寄存器的数据:

使用u反汇编:

使用g命令执行到程序返回前,并查看段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 cx,8 mov di,0 mov ax,a mov ds,ax s: push ds:[di] add di,2 loop s mov ah,4ch int 21h code ends end start
汇编、链接并执行程序的截图:

查看寄存器的数据并用u命令反汇编:

用g命令执行到程序返回前并查看段b的数据:

实验总结
(1)掌握了更多指令的使用方法和注意点。
(2)学会使用div命令和asc码与数值的关系及系统调用来将数字输出成字符。
(3)了解了系统在分配数据段中的存储地址时总是会分配16的倍数,方便CPU数位对齐处理。
(4)编写汇编程序时注意数字的进制,最好在16位进制后加上h,否则容易混淆。dosbox中出现的数据均为十六进制。
(5)使用分段的程序可以使数据和代码分离,同时需要在结束时指明程序的入口。

浙公网安备 33010602011771号