实验2 多个逻辑段的汇编源程序编写与调试
实验任务1
任务1-1
源码
1 assume ds:data, cs:code, ss:stack 2 data segment 3 db 16 dup(0) ; 预留16个字节单元,初始值均为0 4 data ends 5 stack segment 6 db 16 dup(0) ;预留16个字节单元,初始值均为0 7 stack ends 8 code segment 9 start: 10 mov ax, data 11 mov ds, ax 12 mov ax, stack 13 mov ss, ax 14 mov sp, 16 ; 设置栈顶 15 mov ah, 4ch 16 int 21h 17 code ends 18 end start
截图
题目问答
① 在debug中将执行到line17结束、line19之前,记录此时:寄存器(DS) = _ 0770__, 寄存器(SS) =
_0771___, 寄存器(CS) = _0772___
② 假设程序加载后,code段的段地址是X,则,data段的段地址是_X-2__, stack的段地址是__X-1__。
任务1-2
源码
1 assume ds:data, cs:code, ss:stack 2 data segment 3 db 4 dup(0) ; 预留4个字节单元,初始值均为0 4 data ends 5 stack segment 6 db 8 dup(0) ; 预留8个字节单元,初始值均为0 7 stack ends 8 code segment 9 start: 10 mov ax, data 11 mov ds, ax 12 mov ax, stack 13 mov ss, ax 14 mov sp, 8 ; 设置栈顶 15 mov ah, 4ch 16 int 21h 17 code ends 18 end start
截图
题目问答
① 在debug中将执行到line9结束、line11之前,记录此时:寄存器(DS) = _0770___, 寄存器(SS) =
_0771___, 寄存器(CS) = _0772___
② 假设程序加载后,code段的段地址是X____,则,data段的段地址是__X-2__, stack的段地址是
_X-1___。
任务1-3
源码
1 assume ds:data, cs:code, ss:stack 2 data segment 3 db 20 dup(0) ; 预留20个字节单元,初始值均为0 4 data ends 5 stack segment 6 db 20 dup(0) ; 预留20个字节单元,初始值均为0 7 stack ends 8 code segment 9 start: 10 mov ax, data 11 mov ds, ax 12 mov ax, stack 13 mov ss, ax 14 mov sp, 20 ; 设置初始栈顶 15 mov ah, 4ch 16 int 21h 17 code ends 18 end start
截图
题目问答
① 在debug中将执行到line17结束、line19之前,记录此时:寄存器(DS) = _0770___, 寄存器(SS) =
_0772___, 寄存器(CS) = __0774__
② 假设程序加载后,code段的段地址是X,则,data段的段地址是_X-4___, stack的段地址是_X-2___。
任务1-4
源码
1 assume ds:data, cs:code, ss:stack 2 code segment 3 start: 4 mov ax, data 5 mov ds, ax 6 mov ax, stack 7 mov ss, ax 8 mov sp, 20 9 mov ah, 4ch 10 int 21h 11 code ends 12 data segment 13 db 20 dup(0) 14 data ends 15 stack segment 16 db 20 dup(0) 17 stack ends 18 end start
截图
问题回答
① 在debug中将执行到line9结束、line11之前,记录此时:寄存器(DS) = _0772___, 寄存器(SS) =
_0774___, 寄存器(CS) = _0770___
② 假设程序加载后,code段的段地址是X____,则,data段的段地址是_X+2__, stack的段地址是
__X+4__。
任务1-5
问题回答
① 对于如下定义的段,程序加载后,实际分配给该段的内存空间大小是 __⌈N/16⌉*16__。
1 xxx segment 2 db N dup(0) 3 xxx ends
② 如果将程序task1_1.asm, task1_2.asm, task1_3.asm, task1_4.asm中,伪指令 end start 改成
end , 哪一个程序仍然可以正确执行?结合实践观察得到的结论,分析、说明原因。
实验任务2
使用f命令的实验截图:
源代码:
1 assume cs:code 2 code segment 3 mov ax,0b8f0h 4 mov ds,ax 5 6 mov bx,0 7 mov ax,0403h ;低位为03,高位为04 8 mov cx,80 9 10 s: mov [bx],ax ;需要把数字先存入寄存器中 11 add bx,2 12 loop s 13 mov ah,4ch 14 int 21h 15 code ends 16 end
实验截图:
实验任务3
源代码:
1 assume cs:code 2 3 data1 segment 4 db 50,48,50,50,0,48,49,0,48,49 ; ten numbers 5 data1 ends 6 7 data2 segment 8 db 0,0,0,0,47,0,0,47,0,0 ; ten numbers 9 data2 ends 10 11 data3 segment 12 db 16 dup(0) 13 data3 ends 14 15 code segment 16 start: 17 mov ax,data1 18 mov ds,ax 19 20 mov bx,0 21 mov cx,10 22 23 s: mov ax,ds:[bx] 24 add ax,ds:[bx+10h] 25 mov ds:[bx+20h],ax 26 inc bx 27 loop s 28 29 mov ah, 4ch 30 int 21h 31 code ends 32 end start
反汇编:
查看data1,data2,data3:
实验任务4
源码:
1 assume cs:code,ss:stack 2 data1 segment 3 dw 2,0,4,9,2,0,1,9 4 data1 ends 5 6 data2 segment 7 dw 8 dup(0) 8 data2 ends 9 10 stack segment 11 dw 8 dup(0) 12 stack ends 13 14 code segment 15 start: 16 mov ax,data1 17 mov ds,ax 18 mov sp,9 19 mov bx,0 20 mov cx,8 21 s1: push ds:[bx] 22 add bx,2 23 loop s1 24 25 mov ax,data2 26 mov ds,ax 27 mov bx,0 28 mov cx,8 29 30 s2: pop ds:[bx] 31 add bx,2 32 loop s2 33 34 mov ah,4ch 35 int 21h 36 37 code ends 38 end start
实验前截图:
实验后截图:
实验任务5
源码:
1 assume cs:code, ds:data 2 data segment 3 db 'Nuist' 4 db 2, 3, 4, 5, 6 5 data ends 6 code segment 7 start: 8 mov ax, data 9 mov ds, ax 10 mov ax, 0b800H 11 mov es, ax 12 mov cx, 5 13 mov si, 0 14 mov di, 0f00h 15 s: mov al, [si] 16 and al, 0dfh 17 mov es:[di], al 18 mov al, [5+si] 19 mov es:[di+1], al 20 inc si 21 add di, 2 22 loop s 23 mov ah, 4ch 24 int 21h 25 code ends 26 end start
运行截图:
(1)将db 2,3,4,5,6--> 改成: db 5 dup(2)
(2)将db 2,3,4,5,6--> 改成: db 5 dup(5)
问题回答:
(1)line19的作用:将小写字母转换成大写字母,and al, 0dfh,其中0dfh二进制为1101 1111,那么高位第三位是0,无论相与的该位是1还是0,与后结果都是0,那么相当于而二进制数-32,小写字母-32即为大写字母。
(2)line4的作用:8位色彩代码
实验任务6
源代码:
1 assume cs:code, ds:data 2 data segment 3 db 'Pink Floyd '; 16字节 4 db 'JOAN Baez '; 16字节 5 db 'NEIL Young '; 16字节 6 db 'Joan Lennon '; 16字节 7 data ends 8 code segment 9 start: 10 mov ax,data 11 mov ds,ax 12 13 mov ax,data 14 mov es,ax 15 16 mov bx,0 17 mov cx,4 18 19 s0: 20 mov si,cx 21 mov cx,4 22 23 s1: 24 mov al,es:[bx] 25 or al,00100000B 26 mov es:[bx],al 27 inc bx 28 loop s1 29 30 mov cx,si 31 mov bx,0 32 33 mov ax,es 34 inc ax 35 mov es,ax 36 37 loop s0 38 39 40 mov ah, 4ch 41 int 21h 42 code ends 43 end start
实验前截图:
实验后截图:
实验任务7
源代码:
1 assume cs:code, ds:data, es:table 2 data segment 3 db '1975', '1976', '1977', '1978', '1979' 4 dw 16, 22, 382, 1356, 2390 5 dw 3, 7, 9, 13, 28 6 data ends 7 table segment 8 db 5 dup(16 dup(' ')) 9 table ends 10 code segment 11 start: 12 mov ax,data 13 mov ds,ax 14 mov ax,table 15 mov es,ax 16 17 ;年份 18 mov bx,0 ;table的行指针 19 mov si,0 20 mov di,0 21 mov cx,5 22 year: 23 mov dx,cx 24 mov cx,4 25 ;内循环 26 yearin: 27 mov al,byte ptr ds:[di] 28 mov byte ptr es:[bx][si],al 29 inc si 30 inc di 31 loop yearin 32 ;内循环结束 33 mov cx,dx 34 add bx,10h 35 mov si,0 36 loop year 37 38 ;收入 39 mov bx,0 40 mov si,5 41 mov cx,5 42 43 income: 44 mov ax,word ptr ds:[di] 45 mov word ptr es:[bx][si],ax 46 add si,2 47 add di,2 48 mov ax,word ptr ds:[di] 49 mov word ptr es:[bx][si],ax 50 add si,2 51 add di,2 52 53 add bx,10h 54 mov si,5 55 56 loop income 57 58 ;雇员 59 mov bx,0 60 mov si,0Ah 61 mov cx,5 62 employee: 63 mov ax,word ptr ds:[di] 64 mov word ptr es:[bx][si],ax 65 add si,2 66 add di,2 67 68 add bx,10h 69 mov si,0Ah 70 loop employee 71 72 ;人均收入 73 mov bx,0 74 mov si,5 75 mov cx,5 76 77 average: 78 mov ax,word ptr es:[bx][si] 79 add si,2 80 mov dx,word ptr es:[bx][si] 81 add si,3 82 div word ptr es:[bx][si] 83 add si,3 84 mov word ptr es:[bx][si],ax 85 86 add bx,10h 87 mov si,5 88 loop average 89 90 91 mov ah, 4ch 92 int 21h 93 code ends 94 end start
实验前截图:
实验后截图:
实验总结
1.小写字母转大写可以使用and 16进制字母ASCII码, 0DFh来实现,大写字母转小写可以使用or 16进制字母ASCII码, 20h来实现。
2.mov不能用于两个内存数据移动,必须通过寄存器中转