汇编程序
![汇编程序](https://img.360docs.net/img90/1gtu7d74tk8o2qsquw0aggx4b38p76x6-01.webp)
![汇编程序](https://img.360docs.net/img90/1gtu7d74tk8o2qsquw0aggx4b38p76x6-12.webp)
实验1-1——多字节数的运算
⑴、两个长度为3个字节(3B)的二进制无符号数,分别存放在首地址为buf1和buf2的连续内存单元中,编程求这两者之和,并将结果放在起始地址为res 的内存单元中。例如,这两个数据为888888H、456789H,则其和应为
[1]345671H。
源代码如下:
.model small
.model small
.stack
.data
buf1 dd 888888h
buf2 dd 456789h
res dd 0h
.code
start: mov ax,@data
mov ds,ax
mov ax,word ptr buf1;取buf1的低16位
add ax,word ptr buf2;取buf2的低16位+buf1的低16位
mov word ptr res,ax;相加结果存入res
mov ax,word ptr buf1+2;取buf1的高16位
adc ax,word ptr buf2+2;取buf2的高16位+buf1的高16位+CF
mov word ptr res+2,ax;相加结果存入res
;输出
mov cx,3 ;置循环初值
mov si,2
again: mov dl,byte ptr res[si];依次取res的两个字节,由高到低
push cx ;保护循环值cx
mov cl,4
shr dl,cl ;将dl高四位移到低四位
pop cx
or dl,30h ;将dl高四位转化为ASCII
cmp dl,39h ;判断是否大于10
jbe next1
add dl,7 ;加7转化为A到E字母输出
next1: mov ah,2
int 21h
mov dl,byte ptr res[si]
and dl,0fh ;将dl高四位清零
or dl,30h; ;将dl低四位转化为ASCII
cmp dl,39h
jbe next2
add dl,7
next2: mov ah,2
int 21h
dec si
loop again
mov ax,4c00h
int 21h
end start
运行结果截图
⑵、将两数改为3B的压缩BCD码,重复以上实验过程。例如,这两个数据为888888H、456789H,则其和应为[1]345677H(表示[1]345677)。
源代码如下:
.model small
.model small
.stack
.data
buf1 dd 888888h
buf2 dd 456789h
res dd 0h
.code
start: mov ax,@data
mov ds,ax
mov al,byte ptr buf1 ;取buf1的低8位
add al,byte ptr buf2 ;取buf2的低8位+buf1的低8位
daa;调整为十进制
mov byte ptr res,al ;相加结果存入res
mov al,byte ptr buf1+1;取buf1的中间8位
adc al,byte ptr buf2+1;取buf2的中间8位+buf1的中间8位+CF
daa;调整为十进制
mov byte ptr res+1,al ;相加结果存入res
mov al,byte ptr buf1+2;取buf1的高8位
adc al,byte ptr buf2+2;取buf2的高8位+buf1的高8位+CF
daa;调整为十进制
mov byte ptr res+2,al ;相加结果存入res
;输出
mov cx,3 ;置循环初值
mov si,2
again: mov dl,byte ptr res[si];依次取res的两个字节,由高到低
push cx ;保护循环值cx
mov cl,4
shr dl,cl ;将dl高四位移到低四位
pop cx
or dl,30h ;将dl高四位转化为ASCII
cmp dl,39h ;判断是否大于10
jbe next1
add dl,7 ;加7转化为A到E字母输出
next1: mov ah,2
int 21h
mov dl,byte ptr res[si]
and dl,0fh ;将dl高四位清零
or dl,30h; ;将dl低四位转化为ASCII
cmp dl,39h
jbe next2
add dl,7
next2: mov ah,2
int 21h
dec si
loop again
mov ax,4c00h
int 21h
end start
运行结果截图:
实验1-2——BCD码操作
⑴、将存放在首地址为buf的5B的压缩BCD码分离为10B的非压缩BCD码,并存于首地址为res的单元中
原代码如下:
.
.model small
.stack
.data
buf dt 1223568941h;
res dt?
.code
start: mov ax,@data
mov ds,ax
mov cx,5
xor si,si ;置循环次数
lea di,buf ;取其地址
again: mov dl,[di] ;取两个字节先保存低四位后保存高四位and dl,0fh ;置高四位为零
mov byte ptr res[si],dl;保存到res单元
mov dl,[di]
push cx ;保护循环次数
mov cl,4
shr dl,cl ;高四位移到第四位,并置高四位为零
pop cx
inc si
mov byte ptr res[si],dl
inc si
inc di
loop again ;循环继续取值
dec si ;输出,由高位开始输出
mov cx,10
again1: mov dl,byte ptr res[si];依次取res的两个字节,由高到低push cx ;保护循环值cx
mov cl,4
shr dl,cl ;将dl高四位移到低四位
pop cx
or dl,30h ;将dl高四位转化为ASCII
mov ah,2
int 21h
mov dl,byte ptr res[si]
and dl,0fh ;将dl高四位清零
or dl,30h; ;将dl低四位转化为ASCII
mov ah,2
int 21h
dec si
loop again1
mov ax,4c00h
int 21h
end start
运行结果截图
⑵、将存放在首地址为buf的10B的非压缩BCD码合并为5B的压缩BCD 码,并存于首地址为res的单元中。10B的非压缩BCD码数据请自行设计。
源代码如下:
.model small
.stack
.data
buf dt 01020203050608090401h;
res dt?
.code
start: mov ax,@data
mov ds,ax
mov cx,5
xor si,si ;置循环次数
lea di,buf ;取其地址
again: mov dl,[di] ;取两个字节
inc di
mov al,[di] ;再依次取两个字节
push cx
mov cl,4 ;其中高位移四位
shl al,cl
pop cx
or dl,al ;相与后将其前导覆盖
mov byte ptr res[si],dl;保存到res单元
inc si
inc di
loop again ;循环继续取值
dec si ;输出,由高位开始输出
mov cx,5
again1: mov dl,byte ptr res[si];依次取res的两个字节,由高到低
push cx ;保护循环值cx
mov cl,4
shr dl,cl ;将dl高四位移到低四位
pop cx
or dl,30h ;将dl高四位转化为ASCII
mov ah,2
int 21h
mov dl,byte ptr res[si]
and dl,0fh ;将dl高四位清零
or dl,30h; ;将dl低四位转化为ASCII
mov ah,2
int 21h
dec si
loop again1
mov ax,4c00h
int 21h
end start
运行结果截图:
⑶、将存放在内存单元buf(字节)中的BCD码转为相应的数据并存到res(字节)单元。例如将35H转换为二进制数据应得到23H、即十进制的35。
源代码如下:
.model small
.stack
.data
buf db 35h
.code
start: mov ax,@data
mov ds,ax
mov dl,buf
mov cl,4
shr dl,cl
mov bl,dl;bl=0000 0011
mov dl,buf
and dl,0fh;dl=0000 0101
;利用移位指令,实现数值bl乘以10
shl bl,1 ;bl=0000 0110
mov al,bl
shl bl,1
shl bl,1 ;bl=0001 1000
add bl,al;bl=0001 1110
;将乘于十之后的bl与dl相加
add bl,dl;bl=0010 0011
;输出
mov dl,bl
mov cl,4
shr dl,cl
or dl,30h
cmp dl,39h ;判断是否大于10
jbe next1
add dl,7 ;加7转化为A到E字母输出next1: mov ah,2
int 21h
mov dl,bl
and dl,0fh
or dl,30h
cmp dl,39h
jbe next2
add dl,7
next2: mov ah,2
int 21h
mov ax,4c00h
int 21h
end start
运行结果截图:
实验1-3——数据的求和、求均源代码如下:
.model small
.stack
.data
buf dw 0,1,2,3,4,5,6,7,8,9,90,91,92,93,94,95,96,97,98,99 res1 dw?
res2 dw?
res3 dw?
.code
start: mov ax,@data
mov ds,ax
lea di,buf
mov cx,14h ;循环次数,即20D
xor bx,bx ;运算结果保存在bx里面again: adc bx,[di]
add di,2
loop again
mov res1,bx;计算的结果和保存在res1
mov dx,0
mov ax,bx
mov bx,0014h
idiv bx ;计算平均数
mov res2,ax;所得的商保存在res2
mov res3,dx;所得的余数保存在res3
mov bx,res2
mov dl,bh;输出商,形式为十六进制
mov cl,4
shr dl,cl
or dl,30h
mov ah,2
int 21h
mov dl,bh
and dl,0fh
or dl,30h
cmp dl,39h
jbe next1
add dl,7
next1: mov ah,2
int 21h
mov dl,bl
mov cl,4
shr dl,cl
or dl,30h
cmp dl,39h
jbe next2
add dl,7
next2: mov ah,2
int 21h
mov dl,bl
and dl,0fh
or dl,30h
cmp dl,39h
jbe next3
add dl,7
next3: mov ah,2
int 21h
mov ah,2
mov dl,0ah
int 21h
mov bx,res3
mov dl,bh;输出余数,形式为十六进制
mov cl,4
shr dl,cl
or dl,30h
mov ah,2
int 21h
mov dl,bh
and dl,0fh
or dl,30h
cmp dl,39h
jbe next4
add dl,7
next4: mov ah,2
int 21h
mov dl,bl
mov cl,4
shr dl,cl
or dl,30h
cmp dl,39h
jbe next5
add dl,7
next5: mov ah,2
int 21h
mov dl,bl
and dl,0fh
or dl,30h
cmp dl,39h
add dl,7
next6: mov ah,2
int 21h
mov ax,4c00h
int 21h
end start
运行结果截图:
实验1-4——联合移位、代码转换和字符输出
⑴、将存放在首地址为buf、长度为3B的数据联合左移2位。例如,左移前为88
88 88H,左移后应为22 22 20H
源代码如下:
.model small
.stack
.data
buf df 888888h
.code
start: mov ax,@data
mov ds,ax
shl word ptr buf,1 ;低四位左移一位
rcl word ptr buf+2,1;高四位循环左移一位
shl word ptr buf,1 ;低四位左移一位
rcl word ptr buf+2,1 ;高四位循环左移一位
;输出
mov bx,word ptr buf+2
mov dl,bl
and dl,0fh
or dl,30h
mov ah,2
int 21h
mov dl,bl
mov cl,4
shr dl,cl
or dl,30h
int 21h
;以上输出高两个字节
mov bx,word ptr buf
mov dl,bh
mov cl,4
shr dl,cl
or dl,30h
mov ah,2
int 21h
mov dl,bh
and dl,0fh
or dl,30h
mov ah,2
int 21h
;以上输出中间两个字节
mov dl,bl
mov cl,4
shr dl,cl
or dl,30h
mov ah,2
int 21h
mov dl,bl
and dl,0fh
or dl,30h
mov ah,2
int 21h
;以上输出低两个字节
mov ax,4c00h
int 21h
end start
运行结果截图:
⑵、将存放在首地址为buf、长度为3B数据,通过调用INT 21H的AH=02H 子功能、以二进制的形式从屏幕输出。例如,数据为8421A5H,输出应为“100001000010000110100101”。
源代码如下:
.model small
.stack
.data
buf df 8421A5h
.code
start: mov ax,@data
mov ds,ax
mov cx,08h ;联合向左移位,移位8位
again1: shl word ptr buf,1
rcl word ptr buf+2,1
loop again1
mov cx,18h ;输出其二进制形式
again2: shl word ptr buf,1
rcl word ptr buf+2,1;联合向左移位,借助CF输出起二进制形式
mov dl,0
adc dl,30h ;借助adc将进位标志CF转化为ASCII输出
mov ah,2
int 21h
loop again2
mov ax,4c00h
int 21h
end start
运行结果截图:
实验1-5——字符串的输入输出
源代码如下:
.model small
.stack
.data
keynum = 225
string db keynum;定义键盘输入需要的缓冲区
db 0
db keynum dup(0)
string1 db'Input String',"$"
.code
start: mov ax,@data
mov ds,ax
;输出提示信息Input String
mov ah,09h
mov dx,offset string1
int 21h
;输出回车
mov ah,02h
mov dl,0dh
int 21h
;输出换行
mov ah,02h
mov dl,0ah
int 21h
;输入字符串
mov dx,offset string
mov ah,0ah
int 21h
;输出换行
mov dl,0ah
mov ah,2
int 21h
mov bx,offset string+1
mov cl,[bx]
mov ch,0
again: inc bx
mov dl,[bx]
cmp dl,'a'
jb disp
cmp dl,'z';比较是否为小写字母
ja disp
sub dl,20h;将小写字母转化为大写字母
disp: mov ah,2
int 21h
loop again
mov ax,4c00h
int 21h
end start
运行结果截图:
实验1-6——分支形成
⑴、一批单字节有符号数,总共20个,分别统计其中0、正数、负数的个数,并将统计结果分别存放在内存单元res_z、res_p及res_m中。相关数据请自行设计。
源代码如下:
.model small
.stack
.data
count = 20
array dw-4,5,6,0,-2,3,0,-5,-6,5,3,0,-6,8,7,-5,0,4,-3,4 cplus db 0 ;保存正数的个数
cminus db 0 ;保存负数的个数
czero db 0 ;保存零的个数
.code
start: mov ax,@data
mov ds,ax
mov si,offset array
mov cx,count
again: cmp [si],0
jl minus ;小于零转入小于零计数
jz zero ;等于零转入等于零计数
inc cplus ;否则计数正数
jmp next
minus: inc cminus
jmp next
zero: inc czero
next: add si,2
loop again
;输出正数的个数,二进制形式
mov bl,cplus
mov dl,bl
mov cl,4
shr dl,cl
or dl,30h
mov ah,2
int 21h
mov dl,bl
and dl,0fh
or dl,30h
mov ah,2
int 21h
mov ah,2
mov dl,0ah
int 21h
;输出负数的个数,二进制形式
mov bl,cminus
mov dl,bl
mov cl,4
shr dl,cl
or dl,30h
mov ah,2
int 21h
mov dl,bl
and dl,0fh
or dl,30h
mov ah,2
int 21h
mov ah,2
mov dl,0ah
int 21h
;输出零的个数,二进制形式
mov bl,czero
mov dl,bl
mov cl,4
shr dl,cl
or dl,30h
mov ah,2
int 21h
mov dl,bl
and dl,0fh
or dl,30h
mov ah,2
int 21h
mov ax,4c00h
int 21h
end start
运行结果截图:
⑵、调用INT 21H的AH=01H功能,接收从键盘输入的一个字符,当它为“F”或“f”时,输出“FORTRAN”并退出;当它为“B”或“b”时,输出“BASIC”并退出;当它为“C”或“c”时,输出“C/C++”并退出,当它为
“P”或“p”时输出“PASCAL”并退出,如果输入其他字符,则什么也不输出、鸣笛一声退出
源代码如下:
.model small
.stack
.data
string1 db'FORTRAN',"$"
string2 db'BASIC',"$"
string3 db'C/C++',"$"
string4 db'PASCAL',"$"
.code
start: mov ax,@data
mov ds,ax
mov ah,01h
int 21h
cmp al,'F';判断是否输入为F和f
je next1
cmp al,'f'
je next1 ;如果是,转入next1
cmp al,'B';判断是否输入为B和b
je next2
cmp al,'b'
je next2;如果是,转入next2
cmp al,'C';判断是否输入为C和c
je next3
cmp al,'c'
je next3;如果是,转入next3
cmp al,'P';判断是否输入为P和p
je next4
cmp al,'p'
je next4;如果是,转入next4
jmp next5;否则转入next5
next1: mov ah,09h
mov dx,offset string1;显示string1
int 21h
jmp next
next2: mov ah,09h
mov dx,offset string2;显示string2
int 21h
jmp next
next3: mov ah,09h
mov dx,offset string3;显示string3
int 21h
jmp next
next4: mov ah,09h
mov dx,offset string4;显示string4
int 21h
jmp next
next5: mov ah,02h;响铃
mov dl,07h
int 21h
next: mov ax,4c00h
int 21h
end start
运行结果截图:
实验1-7——排序和检索
⑴、从buf开始的内存单元连续存放着20个无序的单字节无符号数,请将它们从小到大进行排序
源代码如下:
.model small
.stack
.data
buf db 25,69,85,55,90,74,69,58,21,4,6,3,8,5,1,23,42,80,26,49
res dw?
flag db 0
.code
start: mov ax,@data
mov ds,ax
cycle: and flag,0;外层循环
mov cx,19 ;做19次比较
mov si,0
again: mov al,buf[si];去其中一值
inc si
cmp al,buf[si];与相邻的一值做比较
jna go
;交换位置
mov bl,buf[si]
mov buf[si],al
mov buf[si-1],bl
inc flag;设置标志不为零
go: loop again
cmp flag,0;判断是否还需要交换
jnz cycle
;输出,为十六进制
lea si,buf
mov cx,20
output: mov dl,[si]
push cx
mov cl,4
shr dl,cl
pop cx
or dl,30h
cmp dl,39h
jbe next1
add dl,7
next1: mov ah,2
int 21h
mov dl,[si]
and dl,0fh
or dl,30h
cmp dl,39h
jbe next2
add dl,7
next2: mov ah,2
int 21h
mov dl," "
mov ah,2
int 21h
inc si
loop output
mov ax,4c00h
int 21h
end start
运行结果截图:
⑵、从buf开始的内存单元连续存放着20个无序的单字节无符号数,编程在其中查找一个确定的数,例如55H。如果找到则将找到的位置(1~20)送res单元,否则将0送res单元
源代码如下:
.model small
.stack
.data
buf db 25,3,55,42,2,74,69,58,21,4,2,3,8,5,1,123,42,253,2,49
res db?
flag db 0
.code
start: mov ax,@data
mov ds,ax
mov al,55 ;与要搜索的值做比较
mov si,offset buf
mov cl,20 ;最坏搜索20次
again: cmp al,[si]
jz done ;找到了
inc si
loop again
mov bl,0 ;没有找到将0送入res
mov res,bl
jmp next
done: mov bl,21 ;找到了将其位置送入res中
sub bl,cl
mov res,bl
next: ;用于输出其位置,十六进制
mov dl,bl
mov cl,4
shr dl,cl
or dl,30h
cmp dl,39h
jbe next1
add dl,7
next1: mov ah,2
int 21h
mov dl,bl
and dl,0fh
or dl,30h
cmp dl,39h
jbe next2
add dl,7
next2: mov ah,2
int 21h
mov ax,4c00h
int 21h
end start
运行结果截图:
没有找到
找到到了
实验1-8——子程序的定义与调用源代码如下:
.model small
.stack
.data
buf db 1h,2h,3h,4h,5h,6h
count = 6
wmed db?;存放平均值
.code
start: mov ax,@data
mov ds,ax
mov ax,count
push ax ;压入数据的个数
mov ax,offset buf
push ax ;压入数据缓冲区的偏移地址
call subpro ;调用子程序
add sp,4 ;平衡堆栈