实验2 多个逻辑段的汇编源程序编写与调试
- 任务1
1-1
1.
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

1).在debug中将执行到line17结束、line19之前时,
Ds=076C
SS=076D
CS=076E
2).
data段的地址是X-2
stack的段地址是X-1
1.2
1.
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

1).在debug中将执行到line17结束、line19之前时,
Ds=076C
SS=076D
CS=076E
2).
data段的地址是X-2
stack的段地址是X-1
实验1.3
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
end start

1).在debug中将执行到line17结束、line19之前时,
Ds=076C
SS=076E
CS=0770
2).
data段的地址是X-4
stack的段地址是X-2
1.4
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

1).在debug中将执行到line9结束、line11之前时,
Ds=076E
SS=07700
CS=076C
2).
data段的地址是X+2
stack的段地址是X+4
1.5
1.
实际分配给该段的内存空间大小是16*【N/16】
2.
\



只有task1_4.asm可以正确执行。
因为只有task1_4.asm在内存中可执行代码在最前面,不指名入口,cpu会把定义的数据也当成指定代码执行了。
- 任务2
assume cs:code
code segment
mov ax, 0b800h ;目标空间的段地址
mov ds, ax
mov ax, 0403H
mov bx, 0f00h
mov cx, 80 ;循环80次
s: mov ds:[bx], ax ;将ax的数据送入b800:bx
add bx, 2 ;一次性写入两个所以bx+2,也可以写两个inc bx
loop s
mov ax, 4c00h
int 21h
code ends
end


虽然效果一样但是用b指令的时候却发现结果不同
- 任务3
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 ax,data2
mov es,ax
mov bx,0
mov cx,10
s1: mov al,es:[bx]
add ds:[bx],al
inc bx
loop s1
mov ax ,data3
mov es,ax
mov bx,0
mov cx,10
s2: mov al,ds:[bx]
mov es:[bx],al
inc bx
loop s2
mov ah, 4ch
int 21h
code ends
end start

data1对应的内存空间数据原始值为076C:0000
data2对应的内存空间数据原始值为076C:0010
data3对应的内存空间数据原始值为076C:0020
相加前

相加后

- 任务4

执行前
data1对应的内存空间数据原始值为076C:0000
data1对应的内存空间数据原始值为076C:0010

执行后

确实反转了
- 任务5
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


line 19 的作用是对字母进行大写化
将【si】与11101111B进行逻辑与运算从而得到大写字母
改成db 5 dup(2)时结果为

改成db 5 dup(5)时结果为


此处数值对应各个字母的颜色,改成db X dup(X)时就变成了单一颜色。
- 任务6
assume cs:code, ds:data
data segment
db 'Pink Floyd '
db 'JOAN Baez '
db 'NEIL Young '
db 'Joan Lennon '
data ends
code segment
start:
mov ax, data
mov ds, ax
mov ax, data
mov es, ax
mov bx, 0
mov cx, 4 ; CX=4,外循环执行4次
s1:
mov si, cx
mov cx, 4 ; CX=4,内循环执行4次
s2:
mov al, es:[bx]
or al, 20h ; ds:[bx]相与, 转换成小写
mov es:[bx], al
inc bx
loop s2
mov cx, si
mov bx, 0
mov ax, es
inc ax
mov es, ax
loop s1
mov ah, 4ch
int 21h
code ends
end start

进入循环前可以看到首字母存在大写

通过U指令找到后发现到002e中断执行循环结束
首字母变成了小写
从ascii码角度看,大写字母比小写字母小32,所以通过加2H也能实现,
其实在大写字母范围内,or指令正好也能实现了加32这个功能
- 任务7
assume cs:code, ds:data, es:table
data segment
db '1975', '1976', '1977', '1978', '1979'
dd 16, 22, 382, 1356, 2390
dw 3, 7, 9, 13, 28
data ends
table segment
db 5 dup( 16 dup(' ') )
table ends
code segment
start:
mov ax, data
mov ds, ax
mov ax, table
mov es, ax
mov bx, 0
mov si, 0
mov di, 0
mov cx, 5 ; CX=5,5行数据循环5次
year:
mov dx, cx
mov cx, 4 ; 每个年份4个数字
yyyy:
mov al, byte ptr ds:[di]
mov byte ptr es:[bx][si], al
inc si
inc di
loop yyyy ;年份
mov cx, dx
add bx, 10h ; 换行操作
mov si, 0
loop year
mov bx, 0
mov si, 5
mov cx, 5 ; 初始化收入的位置开始填入
sala:
mov ax, word ptr ds:[di]
mov word ptr es:[bx][si], ax
add si, 2
add di, 2
mov ax, word ptr ds:[di]
mov word ptr es:[bx][si], ax
add si, 2
add di, 2
add bx, 10h
mov si, 5
loop sala
mov bx, 0
mov si, 0Ah
mov cx, 5 ; 放雇员
empl:
mov ax, word ptr ds:[di]
mov word ptr es:[bx][si], ax
add si, 2
add di, 2
add bx, 10h
mov si, 0Ah
loop empl
mov bx, 0
mov si, 5
mov cx, 5 ; 算平均收入
aver:
mov ax, word ptr es:[bx][si]
add si, 2
mov dx, word ptr es:[bx][si]
add si, 3
div word ptr es:[bx][si]
add si, 3
mov word ptr es:[bx][si], ax
add bx, 10h
mov si, 5
loop aver
mov ah, 4ch
int 21h
code ends
end start


总结:
汇编语言一样可以进行嵌套循环,但是和c语言什么不同就是不能for(i){for(j){}}这样用两个字母控制内外循环次数,所以在内外循环的时候需要注意保存一下外循环用的cx,不然就不知道循环到哪里去了。
实验2填充数据的时候高位显示颜色低位为数字所以虽然是填充0304但是指令里缺要打成0403
任务5中 db X dup(A) X表示重复定义的次数,A重复定义的内容,也就是为什么改了之后字体颜色变成单一的了。
任务7嵌套循环的时候有点数组的感觉但是行列没数组那么好控制了
不会搞超链接,排版地狱()
浙公网安备 33010602011771号