更多请访问我的站点:https://www.liangking.me/2017/04/08/assembly-experiment3/
l 理解程序在访问内存单元时采用的各种寻址方式
l 学会基于字符的ASCII编码,进行大小写转换、简单加密等方法
l 学会用loop指令,结合寻址方式,编制单层和双层循环程序解决问题
二、实验内容过程记录
任务0-完成本周课堂程序的调试
(1)有8位IT菜鸟工程师,第一行数据是他们的基本工资,第二行是绩效工资,编程求出总工资放在第三行。
data segment
dw 6290, 7230, 2943, 3360, 7469, 6871,3067, 3086
dw 7288, 7160, 5733, 7030, 5281, 6891,4853, 4539
dw 0,0,0,0,0,0,0,0
data ends
源程序:
assume cs:codesg, ds:datasg
datasg segment
dw 6290, 7230, 2943,3360, 7469, 6871, 3067, 3086
dw 7288, 7160, 5733,7030, 5281, 6891, 4853, 4539
dw 0,0,0,0,0,0,0,0
datasg ends
codesg segment
start: mov ax, datasg
mov ds, ax
mov cx, 8 ;循环8次
mov bx, 0 ;作为偏移地址
s: mov ax, [bx] ;实现上下两行相加
add ax, [bx+16]
mov [bx+32], ax ;两数相加的结果放到第三行同一列
add bx,2
loop s
mov ax,4c00h
int 21h
codesg ends
end start
运行结果:
(2)在下面的数据段中,给出了全班5名同学OS、AL、SE、DB课程的成绩,请编程计算出总成绩,写在0值处
datasg segment
dw 54, 74, 71, 52, 0
dw 68, 54, 93, 95, 0
dw 81, 52, 97, 67, 0
dw 98, 77, 69, 99, 0
dw 79, 71, 69, 73, 0
datasg ends
源程序:
assumecs:codesg,ds:datasg
datasg segment
dw 54,74,71,52,0
dw 68,54,93,95,0
dw 81,52,97,67,0
dw 98,77,69,99,0
dw 79,71,69,73,0
datasg ends
codesg segment
start:mov ax,datasg
mov ds, ax
mov cx,5 ;共处理5组数据
mov si,0 ;基址
s0:mov dx, cx ;外层循环将cx保存到dx中
mov cx,4 ;每行累加4个数
mov ax,0 ;累加中间寄存器
mov bx,0 ;偏移地址
s: add ax,[si+bx] ;每个数都加到ax中
add bx,2
loop s
mov [bx+si],ax ;将数据存入内存
mov cx,dx
add si,10 ;找到下一组数据地址
loop s0
mov ax,4c00h
int 21h
codesg ends
end start
运行结果:
任务1-字符串加密
(1)编程为datasg段中字符串中的每个字符加密,加密规则是:每个字符的ASCII值加4。加密好的字符写在待加密字符的后面
assumecs:codesg,ds:datasg
datasg segment
db 'aah, I love you!'
db '................'
datasg ends
codesg segment
start: (写程序)
mov ax,4c00h
int 21h
codesg ends
end start
源程序:
assumecs:codesg,ds:datasg
datasg segment
db 'aah, I love you!'
db '................'
datasg ends
codesg segment
start: movax,datasg
mov ds,ax
mov ax,0
mov bx,0
mov cx,16
s:mov al,[bx] ;将一个字节移入al
add al,4
mov [bx+16],al ;存数
inc bx
loop s
mov ax,4c00h
int 21h
codesg ends
end start
运行结果:
(2)编程为datasg中的每个字符串加密,加密的规则是,每行第1个字符ASCII码加1,第2个字符ASCII码加2,依类类推。已知每个字符串固定为16个字符,非空格字符不足16的,后都是空格。加密后的符号替代原字任,就写在原处。
datasg segment
db 'He Li Jian '
db 'Zhai Yi Ming '
db 'Sun Xue Jiao '
db 'Ma Wen Ming '
datasg ends
源程序:
assume cs:codesg,ds:datasg
datasg segment
db 'He Li Jian '
db 'Zhai Yi Ming '
db 'Sun Xue Jiao '
db 'Ma Wen Ming '
datasg ends
codesg segment
start: mov ax,datasg
mov ds,ax
mov ax,0 ;存储相加的和
mov bx,0 ;偏移地址
mov cx,4
s0:mov dx,cx ;暂存cx
mov cx,16 ;循环16次
mov si,1 ;从1开始
s:mov ax,si
add al,[bx]
mov [bx],al
inc si
inc bx
loop s
mov cx,dx
loop s0
mov ax,4c00h
int 21h
codesg ends
end start
运行结果:
任务2-转圈求和
(1)写程序,对给出的8个数,将相邻的数求和(最后写第一个数与最后一个数的和),并把结果写在其后。在下面的示例中,求和的结果为3 5 7 9 11 13 15 9。
datasg segment
dw 1, 2, 3, 4, 5, 6, 7, 8
dw 0,0,0,0,0,0,0,0
datasg ends
提示1:相邻的两数,若前一数用[si]指示,相邻的后面一数则为[si+2]
提示2:前7个和数可以用统一的规则做出,最后一个和数,呃,要回头去找,不妨特殊处理。
源程序:
assumecs:codesg,ds:datasg
datasg segment
dw 1, 2, 3, 4, 5, 6, 7, 8
dw 0,0,0,0,0,0,0,0
datasg ends
codesg segment
start:movax,datasg
mov ds,ax
mov ax,0;存储相加的和
mov bx,0
mov si,0
mov cx,7;先循环7次
s:add ax,[bx] ;相邻两数相加
add ax,[bx+2]
mov [bx+16],ax ;结果放入内存
add bx,2
mov ax,0
loop s
add ax,[si]
add ax,[bx]
mov [bx+16],ax
mov ax,4c00h
int 21h
codesg ends
end start
运行结果:
(2)若要求将结果写在提供源数据的位置上,而不是在随后的空间中呢?
源程序:
assume cs:codesg,ds:datasg
datasg segment
dw 1, 2, 3, 4, 5, 6, 7, 8
dw 0,0,0,0,0,0,0,0
datasg ends
codesg segment
start:mov ax,datasg
movds,ax
movax,0 ;存储相加的和
movbx,0
movcx,7
movdx,[bx] ;将第一个数先存起来
s:add ax,[bx];相邻两数相加
add ax,[bx+2]
mov [bx],ax ;结果放入内存
add bx,2
mov ax,0
loops
add ax,[bx]
add ax,dx
mov [bx],ax
mov ax,4c00h
int 21h
codesg ends
end start
运行结果:
O(事实):掌握了多种内存寻址的方式。
R(感受):现在可以实现多种寻址方法了。
I(思考):多种寻址方式便于实现各种功能。
D(决定):要熟悉掌握各种寻址方法,方便处理内存。