实验 2 多个逻辑段的汇编源程序编写与调试
实验 2 多个逻辑段的汇编源程序编写与调试
实验结论
1. 实验任务 1
-
任务 1-1
-
task1_1.asm 源码
assume ds:data, cs:code, ss:stack data segment db 16 dup(0) data ends stack segment db 16 dup(0) stack ends code segment start: mov ax, data mov ds, ax mov ax, stack mov ss, ax mov sp, 16 mov ah, 4ch int 21h code ends end start
-
task1_1 调试到 line17 结束、line19 之前截图
-
问题回答
① 在 debug 中将执行到 line17 结束、line19 之前,记录此时:寄存器(DS) =076C
, 寄存器(SS) =076D
, 寄存器(CS) =076E
。
② 假设程序加载后,code 段的段地址是 X,则,data 段的段地址是X-2
, stack 的段地址是X-1
。
-
-
任务 1-2
-
任务 task1_2.asm 源码
assume ds:data, cs:code, ss:stack data segment db 4 dup(0) data ends stack segment db 8 dup(0) stack ends code segment start: mov ax, data mov ds, ax mov ax, stack mov ss, ax mov sp, 8 mov ah, 4ch int 21h code ends end start
-
task1_2 调试到 line17 结束、line19 之前观察寄存器 DS, CS, SS 值的截图。
-
问题回答
① 在 debug 中将执行到 line17 结束、line19 之前,记录此时:寄存器(DS) =076C
,寄存器(SS) =076D
, 寄存器(CS) =076E
。② 假设程序加载后,code 段的段地址是 X,则,data 段的段地址是
X-2
stack 的段地址是X-1
。
-
段占用空间连续且为 16 字节的整数倍。
- 任务 1-3
-
任务 task1_3.asm 源码
assume ds:data, cs:code, ss:stack data segment db 20 dup(0) data ends stack segment db 20 dup(0) stack ends code segment start: mov ax, data mov ds, ax mov ax, stack mov ss, ax mov sp, 20 mov ah, 4ch int 21h code ends
-
task1_3 调试到 line17 结束、line19 之前观察寄存器 DS, CS, SS 值的截图
-
问题回答
① 在 debug 中将执行到 line17 结束、line19 之前,记录此时:寄存器(DS) =076C
, 寄存器(SS) =076E
, 寄存器(CS) =0770
② 假设程序加载后,code 段的段地址是 X,则,data 段的段地址是X - 4
, stack 的段地址是X - 2
-
- 任务 1-4
-
任务task1_4.asm源码
assume ds:data, cs:code, ss:stack code segment start: mov ax, data mov ds, ax mov ax, stack mov ss, ax mov sp, 20 mov ah, 4ch int 21h code ends data segment db 20 dup(0) data ends stack segment db 20 dup(0) stack ends end start
-
task1_4调试到line17结束、line19之前观察寄存器DS, CS, SS值的截图
-
问题回答
① 在debug中将执行到line9结束、line11之前,记录此时:寄存器(DS) =076E
, 寄存器(SS) =0770
, 寄存器(CS) =076C
② 假设程序加载后,code段的段地址是X,则,data段的段地址是X + 2
, stack的段地址是X + 4
。
-
- 任务1-5
- 基于上述四个实验任务的实践、观察,总结并回答:
① 对于如下定义的段,程序加载后,实际分配给该段的内存空间大小是 $\lceil N / 16 \rceil$(向上取整)。
② 如果将程序task1_1.asm, task1_2.asm, task1_3.asm, task1_4.asm中,伪指令 end start 改成 end , 哪一个程序仍然可以正确执行。结合实践观察得到的结论,分析、说明原因。xx segment db N dup(0) xxx ends
- task1_5.asm 可以运行,其代码段位于程序首部;
- 基于上述四个实验任务的实践、观察,总结并回答:
2. 实验任务 2
编写一个汇编源程序,实现向内存单元b800:0f00 ~ b800:0f9f连续160字节,依次重复填充十六进制数据03 04。
在debug中,使用f命令,向内存单元批量填写数据。
-f b800:0f00 0f9f 03 04
把内存单元区间b800:0f00 ~ b800:0f9f连续160个字节,依次重复填充十六进制数据03 04。
-
汇编源代码
ASSUME CS:CODE CODE SEGMENT MOV AX, 0B800H MOV DS, AX MOV BX, 0F00H MOV AX, 0403H MOV CX, 009FH s: MOV [BX], AX INC BX LOOP s MOV AX, 4C00H INT 21H CODE ENDS END
-
运行结果截图
3. 实验任务 3
已知 8086 汇编源程序 task3.asm 代码片段如下。
task3.asm
要求:
① 编程实现把逻辑段data1和逻辑段data2的数据依次相加,结果保存到逻辑段data3中。
② 在debug中加载、反汇编、调试。在数据项依次相加前,和相加后,分别查看三个逻辑段data1, data2, data3对应的内存空间,确认逐一相加后,结果的确保存在了逻辑段data3中。
-
补充完整后的汇编源代码
assume cs:code data1 segment db 50, 48, 50, 50, 0, 48, 49, 0, 48, 49 ; ten numbers data1 ends data2 segment db 0, 0, 0, 0, 47, 0, 0, 47, 0, 0 ; ten numbers data2 ends data3 segment db 16 dup(0) data3 ends code segment start: mov ax, data1 mov ds, ax mov bx, 0 mov si, 16 mov di, 32 mov cx, 10 s: mov ax, [bx] add ax, [si] mov [di], ax inc bx inc si inc di loop s mov ax, 4C00H int 21H code ends end start
-
在debug中加载、反汇编、调试截图
-
要求给出,在数据项依次相加之前,查看逻辑段data1, data2, data3对应的内存空间数据原始值的debug命令和截图
-
以及,依次相加之后,查看逻辑段data1, data2, data3对应的内存空间数据原始值的debug命令和截图
-
4. 实验任务4
-
补充完整后的汇编源代码
assume cs:code data1 segment dw 2, 0, 4, 9, 2, 0, 1, 9 data1 ends data2 segment dw 8 dup(?) data2 ends code segment start: mov ax, data1 mov ds, ax mov si, 0 mov di, 1eh mov cx, 8 s: mov ax, [si] mov [di], ax add si, 2 sub di, 2 loop s mov ah, 4ch int 21h code ends end start
-
在debug中加载、反汇编、调试截图
-
要求给出,在程序退出前,使用d命令查看数据段data2对应的内存空间的截图。
5. 实验任务5
-
task5.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
-
运行结果截图
-
使用debug工具对程序进行调试,使用g命令一次性执行到程序返回前(即 line25 执行之后、line27 执行之前)的截图
-
源代码中line19的作用是?
- 将小写字符 ASCII 码通过与运算 (AND 1101 1111) $(DF)_16 = (1101 1111)_2$ 转换为大写字符 对应的 ASCII 码
- A-Z 0100 0001 ~ 0101 1010
- a-z 0110 0001 ~ 0111 1010
-
源代码中 data 段 line4 的字节数据的用途是?
- 通过尝试修改数据段中第二段数字,猜测其决定对应字符的显示颜色
6. 实验任务 6
要求:
① 补全程序,将data段中的每行第一个单词从大写->小写。
② 在debug中加载程序,反汇编,执行到 line13 退出前,用 d 命令查看 data 段对应的内存空间,确认每行第一个单词已经由大写->小写。
-
task6.asm 源代码
assume cs:code, ds:data data segment db 'Pink Floyd ' db 'JOAN Baez ' db 'NEIL Young ' db 'Joan Lennon ' data ends stack segment db 16 dup(?) stack ends code segment start: mov ax, data mov ds, ax mov ax, stack mov ss, ax mov cx, 4 mov bx, [0] s1: push cx mov cx, 4 s2: mov al, [bx] or al, 20h mov [bx], al inc bx loop s2 add bx, 12 pop cx loop s1 mov ah, 4ch int 21h code ends end start
- 通过 ASCII 码将大写字符转换为小写字符需要或
0010 0000
即 $20H$- A-Z 0100 0001 ~ 0101 1010
- a-z 0110 0001 ~ 0111 1010
- 通过 ASCII 码将大写字符转换为小写字符需要或
-
在 debug 中加载、反汇编、调试截图
- 要求给出,在程序退出前,使用 d 命令查看数据段 data 对应的内存空间的截图。
- 要求给出,在程序退出前,使用 d 命令查看数据段 data 对应的内存空间的截图。
7. 实验任务 7
-
task7.asm源码
assume cs:code, ds:data, es:table data segment db '1975', '1976', '1977', '1978', '1979' dw 16, 22, 382, 1356, 2390 dw 3, 7, 9, 13, 28 data ends table segment db 5 dup( 16 dup(' ') ) ; table ends stack segment db 16 dup(?) stack ends code segment start: mov ax, data mov ds, ax mov ax, table mov es, ax mov ax, stack mov ss, ax mov bx, 0 mov di, 0 mov cx, 5 s1: push cx mov cx, 4 s2: mov al, [bx] mov es:[di], al inc bx inc di loop s2 add di, 12 pop cx loop s1 mov di, 0 mov bx, 0 mov cx, 5 s3: mov ax, [20 + bx] mov es:[di + 5], ax mov dl, [30 + bx] div dl mov ah, 0 mov es:[di + 13], ax mov ax, [30 + bx] mov es:[di + 10], ax add di, 10h add bx, 2 loop s3 mov ah, 4ch int 21h code ends end start
- 循环 s1 遍历表格中每一行的年份,s2 遍历年份的每一个字符,将其赋值至 table 每行行首
- 循环 s3 遍历表格中每一行的数据,每一个数据占 2 字节(1 机器字)
di
为每行行首地址di + 5
为收入地址,20 + bx
为数据段中收入地址di + 10
为雇员人数地址,30 + bx
为数据段中雇员人数地址di + 13
为人均收入地址
- 16 bit / 8 bit 除法,被除数为
ax
, 将商存在al
余数存在ah
中
-
调试截图
-
查看 table 段原始数据信息截图
-
在 debug 中运行到程序退出之前,使用 d 命令查看 table 段对应的内存空间的截图,确认信息是否按要求结构化地写入到指定内存
-