实验3 多个段的汇编源程序编写与调试
1. 实验任务1
① 使用任意文本编辑器,录入汇编源程序task1.asm。
1 assume cs:code, ds:data 2 data segment 3 db 'Nuist' 4 db 5 dup(2) 5 data ends 6 7 code segment 8 start: 9 mov ax, data 10 mov ds, ax 11 12 mov ax, 0b800H 13 mov es, ax 14 15 mov cx, 5 ;定义步长为5 16 mov si, 0 ;数据段下标,每次加一 17 mov di, 0f00h ;附加段下标,为显存区域 18 s: mov al, [si] 19 and al, 0dfh ;小写变大写 20 mov es:[di], al ;字母数据 21 mov al, [5+si] 22 mov es:[di+1], al ;颜色信息 23 inc si 24 add di, 2 25 loop s 26 27 mov ah, 4ch 28 int 21h 29 code ends 30 end start
② 使用masm、link对task1.asm进行汇编、链接,得到可执行文件task1.exe,运行并观察结果
③ 使用debug工具对程序进行调试,执行到程序返回前,即line27之前,观察结果
这里数据段占16字节,所以反汇编时0~2a
④ 修改line4里5个字节单元的值,重新汇编、链接、运行,观察结果
line4的字节数据存放数据颜色信息
2. 实验任务2
编写程序,在屏幕上以十进制整数形式打印输出这5个两位数。
1 assume cs:code, ds:data 2 data segment 3 db 23, 50, 66, 71, 35 4 data ends 5 6 code segment 7 start: 8 mov ax,data 9 mov ds,ax 10 11 mov cx,5 12 mov si,0 13 14 s: mov ah,0 15 mov al,[si] 16 mov bl,10 17 div bl ;利用除法div,计算每个数位上的数值 18 mov bx,ax ;防止与下面一条指令混淆,将ax里的数据保存在bx寄存器里 19 20 mov ah,2 21 or bl,30h ;数值->数字字符 22 mov dl,bl 23 int 21h ;利用系统功能调用int 21h中的2号子功能,输出单个字符 24 25 mov ah,2 26 or bh,30h 27 mov dl,bh 28 int 21h 29 30 mov ah,2 31 mov dl,' ' 32 int 21h 33 34 inc si 35 loop s 36 37 mov ax,4c00h 38 int 21h 39 code ends 40 end start
3. 实验任务3
① task3.asm源码
1 assume cs:code, ds:data, ss:stack 2 data segment 3 dw 0123h, 0456h, 0789h, 0abch, 0defh, 0fedh, 0cbah, 0987h 4 data ends 5 6 stack segment 7 dw 0, 0, 0, 0, 0, 0, 0, 0 8 stack ends 9 10 code segment 11 start: mov ax,stack 12 mov ss, ax 13 mov sp,16 14 15 mov ax, data 16 mov ds, ax 17 18 push ds:[0] 19 push ds:[2] 20 pop ds:[2] 21 pop ds:[0] 22 23 mov ax,4c00h 24 int 21h 25 26 code ends 27 end start
② CPU执行程序,程序返回前,data段中的数据:23 01 56 04 89 07 BC 0A EF 0D ED 0F BA 0C 87 09
CPU执行程序,程序返回前,cs=076C,ss=076B,ds=076A
设程序加载后,code段的段地址为X,则data段的段地址为X-2,stack段的段地址为X-1
4. 实验任务4
① task4.asm
1 assume cs:code, ds:data, ss:stack 2 data segment 3 dw 0123h, 0456h 4 data ends 5 6 stack segment 7 dw 0, 0 8 stack ends 9 10 code segment 11 start: mov ax,stack 12 mov ss, ax 13 mov sp,16 14 15 mov ax, data 16 mov ds, ax 17 18 push ds:[0] 19 push ds:[2] 20 pop ds:[2] 21 pop ds:[0] 22 23 mov ax,4c00h 24 int 21h 25 26 code ends 27 end start
② 1) CPU执行程序,程序返回前,data段中的数据:23 01 56 04
2) CPU执行程序,程序返回前,cs=076C,ss=076B,ds=076A
3) 设程序加载后,code段的段地址为X,则data段的段地址为X-2,stack段的段地址为X-1
4) 对于定义如下的段:
name segment
......
name ends
如果段中的数据占N个字节,则程序加载后,该段实际占有的空间为:16k(k>=N/16),所以下图反汇编时不应该是 -u 0 31,而是 -u 0 21
5. 实验任务5
① task5.asm
1 assume cs:code, ds:data, ss:stack 2 3 code segment 4 start: mov ax,stack 5 mov ss, ax 6 mov sp,16 7 8 mov ax, data 9 mov ds, ax 10 11 push ds:[0] 12 push ds:[2] 13 pop ds:[2] 14 pop ds:[0] 15 16 mov ax,4c00h 17 int 21h 18 19 code ends 20 data segment 21 dw 0123h, 0456h 22 data ends 23 24 stack segment 25 dw 0,0 26 stack ends 27 end
② 1) CPU执行程序,程序返回前,data段中的数据:23 01 56 04
2) CPU执行程序,程序返回前,cs=076A,ss=076E,ds=076D
3) 设程序加载后,code段的段地址为X,则data段的段地址为X+3,stack段的段地址为X+4
6. 实验任务6
将最后一条伪指令“end start”改为“end"(也就是说,不指明程序的入口),则哪个程序仍可以正确执行?
答:task5还可以正确执行,因为它代码段放在开始,即使不指明程序入口,也从代码段开始执行。
7. 实验任务7
① task7.asm
1 assume cs:code 2 a segment 3 db 1,2,3,4,5,6,7,8 4 a ends 5 6 b segment 7 db 1,2,3,4,5,6,7,8 8 b ends 9 10 c1 segment 11 db 8 dup(0) 12 c1 ends 13 14 code segment 15 start: 16 mov ax,a 17 mov ds,ax 18 19 mov si,0 20 mov cx,8 21 s: mov ax,[si] 22 add ax,[16+si] 23 mov [32+si],ax 24 25 inc si 26 loop s 27 28 mov ah, 4ch 29 int 21h 30 31 code ends 32 end start
② 结果截图
8. 实验任务8
① task8.asm
1 assume cs:code 2 a segment 3 dw 1,2,3,4,5,6,7,8,9,0ah,0bh,0ch,0dh,0eh,0fh,0ffh 4 a ends 5 6 b segment 7 dw 8 dup(0) 8 b ends 9 10 code segment 11 start: 12 mov ax,a 13 mov ds,ax 14 15 mov ax,b 16 mov ss,ax 17 mov sp,16 18 19 mov bx,0 20 21 s: push ds:[bx] 22 add bx,2 23 loop s 24 25 mov ah, 4ch 26 int 21h 27 code ends 28 end start
② 结果截图
疑惑:
task4 和task5数据段、代码段、栈段都相同,只是放置的顺序不同,为何task4的cx=42,而task5的cx=44
task4
task5