【汇编】实验(下)
实验课作业,实验截图就不放啦~放一些代码
实验五:
- 实验任务一:设一字节变量string中存放一个字符串,以0DH为结束标志。编程求字符串长度,并送字节变量count中,给出你的实验结果。
该程序思路如下:
先自行定义一个字符串“ajsidk”,存入内存单元。将该字符串一个一个与0DH进行比较,如果不相同,则比较后面一位,并且count+1;如果相同,则退出程序,count数不变。
程序代码如下:
DATAS SEGMENT
string DB 'ajsidk',0DH
count DB ?;此处输入数据段代码
DATAS ENDS
STACKS SEGMENT
;此处输入堆栈段代码
STACKS ENDS
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
MOV AX,DATAS
MOV DS,AX
MOV SI,0
MOV count,0
L1:
CMP string[SI],0DH
JZ L2
INC SI
INC count
JMP L1
L2:
MOV AH,4CH
INT 21H
CODES ENDS
END START
2. 实验任务二:下面这个子程序完成什么功能,给出你计算的X和Y。
data dw (n个数)
x dw ?,?
……
xor ax,ax
xor dx,dx
lea bx, data
mov cx, n
again: add ax,[bx]
adc dx,0
inc bx
inc bx
loop again
mov x,ax
mov x+2,dx
……
解答:
该程序实现的功能是对字数组进行求和,并对进位进行记录操作,DX中存入的数据为进位次数,AX中数据为字数组求和结果。
完整代码如下:
DATAS SEGMENT
data dw 1,2,3,4,6
x dw ?,?;此处输入数据段代码
n dw 5
DATAS ENDS
STACKS SEGMENT
;此处输入堆栈段代码
STACKS ENDS
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
MOV AX,DATAS
MOV DS,AX
;此处输入代码段代码
xor ax,ax;ax置0
xor dx,dx;dx置0
lea bx,data;
mov cx, n ;ax置0
again:
add ax,[bx]
adc dx,0 ;带位加法,dx=dx+0
inc bx;bx++
inc bx
loop again
mov x,ax
mov x+2,dx
MOV AH,4CH
INT 21H
CODES ENDS
END START
3. 实验任务三:假定给字节变量char预留26个单元空间,编写程序把字母A~Z依次存放进去。
该程序思路如下:
首先预留26个单元空间给字节变量char,将41H即字符‘A’传入BX中,将其传入AL寄存器,循环传入char数组中,每次循环将AL加1。再对计数器进行判断是否等于26,若等于,则退出循环,完成存放;若不等于则将AL+1,继续循环。
该程序代码如下:
DATAS SEGMENT
char DB 0,26 dup(?)
DATAS ENDS
STACKS SEGMENT
;此处输入堆栈段代码
STACKS ENDS
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
MOV AX,DATAS
MOV DS,AX
MOV DI,0
MOV BL,41H
MOV AL,BL
L1:
MOV char[DI],AL
INC AL
INC DI
CMP DI,1AH
JZ L2
JMP L1
L2:
MOV AH,4CH
INT 21H
CODES ENDS
END START
4. 实验任务四:在数据段定义一字符串str1,编写程序将字符串反序,保存在字符串str2中。
该程序思路如下:
先定义一个字符串str1为‘!dlrow olleh’,定义str2为需要倒叙存入的字符串。为了内存空间展示的时候更规整美观,在定义str2之前再定义一个str11,长度为4,这样str2首地址正好为0010。
随后利用DI和SI进行计数,取str1最后一位,存入到str2第一位中,并进行判断。若DI等于str1中的字符串长度,则结束循环;若不相等,则DI+1,SI-1,继续进行循环,完成str1倒序输入至str2中的任务。
该程序代码如下:
DATAS SEGMENT
str1 DB '!dlrow olleh'
str11 DB 4 dup(?)
str2 DB 12 dup(?);此处输入数据段代码
DATAS ENDS
STACKS SEGMENT
;此处输入堆栈段代码
STACKS ENDS
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
MOV AX,DATAS
MOV DS,AX
MOV SI,0BH
MOV DI,0
L1:
MOV AL,str1[SI]
MOV str2[DI],AL
INC DI
DEC SI
CMP DI,0CH
JZ L2
JMP L1
L2:
MOV AH,4CH
INT 21H
CODES ENDS
END START
实验六:
- 练习体会伪指令伪操作的实际含义:DB、DW、TYPE、LENGTH、SIZE、$、EQ、=、LABLE、THIS、PTR、ORG等。
1、OFFSET
变量是数据的存放地,对变量最常见的操作是从变量中取出数据和把数据放人变量中。
实现这些操作有直接法和间接法两种方法。
以该寄存器加方括号的形式指明是用寄存器中的内容作为偏移地址,操作数在相应的内存
把保留字OFFSET加在变量名字的前面,表示取该变量的偏移地址。汇编程序把"OFFSET变量名"作为一个常量处理,而常量本身是没有类型的。
不论变量在定义时是什么类型,在它的名字前面加上OFFSET后就变成了一个常量。
但是,既然"OFFSET变量名"是用来取变量的偏移地址,而偏移地址是有可能超过255的,超过255时当然就不能把它送到字节型寄存器中。也就是说.在没有准确掌握某个变量的偏移地址时,不要想当然地认为它的偏移地址会小于255。
既然"OFFSET变量名"是常量,就可以参与常量的算术运算。
把一个变量的偏移地址取到某个基址或变址寄存器后,就可以用该寄存器间接寻址方式实现对变量的处理。
间接法在高级语言中有着广泛的应用,在C 语言中表现为指针及其相关处理。
2、SEG
无论按直接法还是间接法使用变量,都会涉及变量的段地址问题。在汇编语言程序中,使用变量需要把其所在段的段地址放在某个段寄存器中,一般是放在DS或ES中,取变量的段地址也有两种方法。一是用变量所在段的段名。另一种方法是用 SEC伪指令放在某变量的前面,表示取该变量所在段的段地址。不论是用段名还是用"SEC变量名"的形式,汇编程序都是把它作为常量处理的。
"SEG变量名"的形式甚至还可以用于ASSUME 伪指令中。
3、PTR
PTR是用于指定操作数类型的伪指令,它需要与类型保留字配合使用。
其基本用法是: 类型 PTR 操作数
用法中的"操作数"要求必须是内存型寻址方式。程序中有两种情况需要用到指定类型伪操作;一是操作数本身没有类型,当需要明确该操作数的类型时使用这种用法;另一种情况是已定义的变量本身有确定的类型,程序需要临时当作另一种类型来处理。
4、ORG
ORG伪指令单独占一行,其基本格式是:
ORG 地址表达式
不论段中写的是变量定义还是指令序列,汇编程序总是把段中各有效操作逐行翻译。在偏移地址的安排上,总是把段中第1个有效操作从偏移地址0开始逐个安排。如果某一行指令或变量定义安排的最后一个字节在偏移地址 n,则其下一个有效操作总是从偏移地址n+1开始安排。ORG伪指令的功能就是改变这种安排方式,它用"地址表达式"指定一个新的偏移地址,ORG伪指令后面的内容就从该地址开始安排。
ORG伪指令可以改变段中各变量在定义时原有的次序,按指定情况安排各变量的偏移地址。
5、$
$ 是汇编语言中的一个特殊符号,在汇编语言程序中直接书写,不加引号,这与加引号的字符是不同的。$ 代表汇编程序在处理到 所 在 位 置 时 应 该 安 排 的 偏 移 地 址 值 。 序 中 出 现 的 所在位置时应该安排的偏移地址值。序中出现的 所在位置时应该安排的偏移地址值。序中出现的可以作为常量看待,但是不同位置上的$ 代表的值是不同的。与一般的数据不同的是,通常所说的常量(数值)是没有类型的,包括"OFFSET 变量名"也没有类型,但$ 所表示的数据一定是字型。$一般作为字型变量定义时的一个初值使用。
6、 = 和EQU
应用高级语言编程时,对于程序中经常使用的一个特定的数值,很多程序员喜欢把它定义成一个常量标识符,在书写后面的程序时若遇到该数值,就写相应的常量标识符面不写数值本身。这种做法的最大好处在于方便程序的修改,如果需要把一个程序中使用到的某一数据统一改为另一数据,如果该数据已经定义为常量就只要在定义处修改一次即可,而没有定义成常量时就需要对该数据的每一次出现都做修改。常量定义的基本格式是:
标识符=数值表达式
常量定义可以写在源程序的任何地方,单独占一行,并且遵照"先定义后使用"的原则。
在很多高级语言中,都规定常量不可重复定义,即把一个标识符定义为某数据之后,不能再在程序的某处修改该定义,使其与另一数据相对应。但是在汇编语言中没有这一限制。
- 字节变量AA1和AA2,把从AA1+10存储单元开始的10个字节复制到AA2开始的连续10个单元中。
该程序思路如下:定义字节变量AA1与AA2,AA1为‘1234567890?ABCDEFGHI’,为了AA2能从0020为首地址开始,格式更美观,我在AA2之前定义一个长度为10的AA11变量。将AA1从第11位开始至第20位复制到AA2中。定义计数器SI为0,表示第0位需要复制的数据。随后进行循环,若SI等于11,则退出循环;若不等于,则SI+1,继续循环。
该程序代码如下:
DATAS SEGMENT
AA1 DB '1234567890?ABCDEFGHIJK'
AA11 DB 10 dup(?)
AA2 DB 12 dup(?);此处输入数据段代码
DATAS ENDS
STACKS SEGMENT
;此处输入堆栈段代码
STACKS ENDS
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
MOV AX,DATAS
MOV DS,AX
MOV SI,0
MOV BX,10
L1:
MOV AL,AA1[BX][SI]
MOV AA2[SI],AL
INC SI
CMP SI,0BH
JZ L2
JMP L1
L2:
MOV AH,4CH
INT 21H
CODES ENDS
END START
- 有3个有符号16进制数arX、arY和arZ,编写程序:
(1)如果这3个数都不相等,则显示0;
(2)如果这3个数中有两个数相等,则显示1;
(3)如果这3个数都相等,则显示2。
该题思路如下:
先将arX、arY、arZ分别存入AX,BX,CX中相互进行比较,一共比较三次。比较结果如果是相同的,则result+1,否则不做变化。因此比较三次后,result的结果可能是0,1,3三种情况,如果是0代表没有一次是相同的,即三个数都不相同,显示0;如果是1说明一次相同,即两个数相同,显示1;如果是3说明三次都相同,即三个数相同,显示2。
该题代码如下:
DATAS SEGMENT
arX DW 4
arY DW 3
arZ DW 1
result DW 0;此处输入数据段代码
DATAS ENDS
STACKS SEGMENT
;此处输入堆栈段代码
STACKS ENDS
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
MOV AX,DATAS
MOV DS,AX
MOV AX,arX
MOV BX,arY
MOV CX,arZ
CMP AX,BX
JZ L1
CMP AX,CX
JZ L2
CMP BX,CX
JZ L3
JMP LL
L1:
INC result
CMP AX,CX
JZ L2
CMP BX,CX
JZ L3
JMP LL
L2:
INC result
CMP BX,CX
JZ L3
JMP LL
L3:
INC result
LL:
CMP result,01H
JS L4 ;结果小于1,说明是0,无相等
JZ L5 ;结果为1,2个数相等
JG L6;结果大于1,3个数相等
L4:
MOV dl,30H
MOV AH,02H
INT 21H
JMP LLEND
L5:
MOV DL,31H
MOV AH,02H
INT 21H
JMP LLEND
L6:
MOV DL,32H
MOV AH,02H
INT 21H
JMP LLEND
LLEND:
MOV AH,4CH
INT 21H
CODES ENDS
END START
当我将数据段代码改成
arX DW 3
arY DW 3
arZ DW 1
result DW 0
当我将数据段代码改成
arX DW 3
arY DW 3
arZ DW 3
result DW 0
- 数组array包含有20个有符号数据,编程把它分成两个数组:正数数组arrayP和负数数组arrayN,并分别把这两个数组中的数据个数显示出来。
该程序实现算法简介如下:
将数组中的每个元素都与0用CMP指令进行比较,若大于零,则进arrayP数组;若小于零,则进arrayN数组。另一个数组用于计数,判断与前一个相同,若大于零则KEY1+1,若小于零则KEY2+1。数组的存入需要将两个数组的首地址依次递增才可以实现存入一组完整的正数或负数数组,通过将首地址传入到BX寄存器中,将BX寄存器依次递增即可。
该程序的具体代码与备注如下:
DATAS SEGMENT
array DB 0,1,-2,3,-4,5,-6,7,-8,9,-10,11,-12,13,-14,15,-16,17,-18,19
arrayP DB 0,9 dup(?) ;正数数组
arrayN DB 0,9 dup(?) ;负数数组
KEY1 DB 0 ;正数个数
KEY2 DB 0 ;负数个数
DATAS ENDS
STACKS SEGMENT
;此处输入堆栈段代码
STACKS ENDS
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
MOV AX,DATAS
MOV DS,AX
main proc far
MOV SI,0
L0:
CMP SI,14H
JNZ LL
JZ LEND
LL:
CALL clfy ;正负分类
CALL count ;记录数组元素个数
JMP L0
main endp
clfy proc near ; 正负分类子程序
CMP array[SI],0
JG L1 ;大于则跳转
JL L2 ;小于则跳转
JZ L3 ;等于0
L1: ;判断为正数
MOV AL,array[SI]
MOV arrayP[DI],AL
INC DI
RET
L2: ;判断为负数
CMP SI,2
JZ LL1
JNZ LL2
LL1:
MOV AL,array[SI]
MOV arrayN,AL
LEA BX,arrayN
INC BX
RET
LL2:
MOV AL,array[SI]
MOV [BX],AL
INC BX
RET
L3: ;判断为0
RET
clfy endp
count proc near
CMP array[SI],0
JG L4 ;大于则跳转
JL L5 ;小于则跳转
JZ L6 ;等于0
L4: ;判断为正数
INC KEY1
INC SI
RET
L5: ;判断为负数
INC KEY2
INC SI
RET
L6: ;判断为0
INC SI
RET
count endp
LEND:
MOV AH,4CH
INT 21H
CODES ENDS
END START
实验七:
实验七 循环、分支和子程序的练习
- 把有N个数据的字数组,统计出正数和负数两部分,并保存在数据段。
DATAS SEGMENT
array db 8 DUP(01h), 12 DUP(0ffh)
arrayP db 20 DUP(11h)
arrayN db 20 DUP(22h)
count db ?,?
string1 db 'number of arrayP=$'
string2 db ' number of arrayN=$'
;此处输入数据段代码
DATAS ENDS
STACKS SEGMENT
;此处输入堆栈段代码
STACKS ENDS
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
MOV AX,DATAS
MOV DS,AX
xor ax,ax
xor bx,bx
xor cx,cx
xor dx,dx
mov dh,21d
lea si,array
lea cx,arrayP
lea bx,arrayN
cld
again:
dec dh
JZ q
lodsb
test al,80h
JNZ negative
mov di,cx
stosb
inc cx
jmp again
negative:
mov di,bx
stosb
inc bx
inc ah
jmp again
q:
xor cx,cx
mov dh,20d
mov ch,ah
sub dh,ch
mov count,ah
mov count+1,dh
mov ah,count+1
add ah,30h
cmp ah,3ah
jl printit1
add ah,7h
printit1:
push ax
lea dx,string1
mov ah,09
int 21h
pop ax
mov dl,ah
mov ah,2
int 21h
lea dx,string2
mov ah,09
int 21h
mov ah,count
add ah,30h
cmp ah,3ah
jl printit2
add ah,7h
printit2:
mov dl,ah
mov ah,2
int 21h
;此处输入代码段代码
MOV AH,4CH
INT 21H
CODES ENDS
END START
- 编制程序,把输入的字符串中小写换大写,大写换小写,其它字符不变,并把处理后的字符串输出。
DATAS SEGMENT
;此处输入数据段代码
OUTPUT DB "answer: ",'$'
BUFFER DB 20 ;预定义20字节的空间
DB ? ;待输入完成后,自动获得输入的字符个数
DB 20 DUP(0)
CRLF DB 0AH, 0DH,'$'
string1 db 'aB1^2'
string2 db ?
DATAS ENDS
STACKS SEGMENT
;此处输入堆栈段代码
STACKS ENDS
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
MOV AX,DATAS
MOV DS,AX
mov es,ax
;此处输入代码段代码
LEA DX,BUFFER ;接收字符串
MOV AH, 0AH
INT 21H
MOV AL, BUFFER+1 ;对字符串进行处理
ADD AL, 2
MOV AH, 0
MOV SI, AX
MOV BUFFER[SI], '$'
LEA DX, CRLF ;另取一行
MOV AH, 09H
INT 21H
xor cx,cx
lea si,buffer+2 ;buffer+2为输入的字符串
lea di,string2
cld
mov cl,ds:[buffer+1]
again:
lodsb
cmp al,'$'
jz exit
cmp al,41h
jl other
cmp al,5ah
jle tolower
cmp al,61h
jl other
cmp al,7ah
jle toupper
other:
stosb
loop again
tolower:
add al,20h
stosb
loop again
toupper:
sub al,20h
stosb
loop again
exit:
cld
xor cx,cx
LEA DX, OUTPUT
MOV AH, 09H
INT 21H
mov cl,ds:[buffer+1] ;buffer+1为字符个数
lea si,string2
printit:
lodsb
cmp al,'$'
jz quit
mov dl,al
mov ah,2
int 21h
loop printit
quit:
MOV AH,4CH
INT 21H
CODES ENDS
END START
- 编制程序,统计一个班的成绩,分成80—100、60—79、60以下三个区段统计,并保存统计结果到数据段。
自己定义了一组数组共15个数据,分别为十五名学生的成绩,进行循环判断,若分数在80-100之间,则A内存单元中的数据+1;若分数在60-79之间,B内存单元中的数据+1;若分数在60以下,CC内存单元中的数据+1。
除此之外,需要对XU数组进行排序,运用冒泡排序的思路,进行双重循环即可。
输出时,先将三个区段的人数输出十进制数,再循环输出数组XU。
该题完整代码如下:
DATAS SEGMENT
A DB 0 ;80-100
B DB 0 ;60-79
CC DB 0 ;60以下
XU DB 95,89,79,77,67,90,45,59,60,100,30,50,40,78,33
DATAS ENDS
STACKS SEGMENT
STACKS ENDS
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
MOV AX,DATAS
MOV DS,AX
main proc far
CALL counting
CALL dec_out1
MOV DL,20H
MOV AH,02H
INT 21H
CALL dec_out2
MOV DL,20H
MOV AH,02H
INT 21H
CALL dec_out3
MOV AH,02H
MOV DL,0AH
INT 21H
MOV AH,02H
MOV DL,0DH
INT 21H ;换行
CALL paixu
CALL printoutarray
MOV AH,4CH
INT 21H
main endp
counting proc near
MOV SI,0
L1:
CMP XU[SI],80
JNS L2
CMP XU[SI],60
JNS L3
INC CC
INC SI
CMP SI,15
JZ LL
JMP L1
L2:
INC A
INC SI
CMP SI,15
JZ LL
JMP L1
L3:
INC B
INC SI
CMP SI,15
JZ LL
JMP L1
LL:
RET
counting endp
printoutarray proc near
MOV SI,0
JUDGL:
CMP SI,15
JZ LEND
MOV DL,XU[SI]
MOV CX,1;计数 初始为1
MOV BL,10;每次除10
ONE:
MOV AH,0;清零(存余数)
MOV AL,DL
DIV BL;除10
PUSH AX;进栈
CMP AL,0;是否已除净
JLE ENDL
MOV DL,AL
INC CX
JMP ONE
ENDL:
POP DX
XCHG DH,DL;余数转入DL
ADD DL,30H
MOV AH,2;输出
INT 21H
LOOP ENDL
MOV AH,02H
MOV DL,20H
INT 21H
INC SI
JMP JUDGL
LEND:
RET
printoutarray endp
dec_out1 proc near ;输出A数组个数
push ax
push bx
push cx
push dx
mov bx,10
mov cx,0
MOV aL,A
MOV AH,0
yazhan:
mov dx,0
div bx
push dx
inc cx
cmp ax,0
jz chuzhan
jmp yazhan
chuzhan:
pop dx
add dl,30h
mov ah,2
int 21h
loop chuzhan
pop dx
pop cx
pop bx
pop ax
ret
dec_out1 endp
dec_out2 proc near ;输出B数组个数
push ax
push bx
push cx
push dx
mov bx,10
mov cx,0
MOV aL,B
MOV AH,0
yazhan:
mov dx,0
div bx
push dx
inc cx
cmp ax,0
jz chuzhan
jmp yazhan
chuzhan:
pop dx
add dl,30h
mov ah,2
int 21h
loop chuzhan
pop dx
pop cx
pop bx
pop ax
ret
dec_out2 endp
dec_out3 proc near ;输出CC数组个数
push ax
push bx
push cx
push dx
mov bx,10
mov cx,0
MOV aL,CC
MOV AH,0
yazhan:
mov dx,0
div bx
push dx
inc cx
cmp ax,0
jz chuzhan
jmp yazhan
chuzhan:
pop dx
add dl,30h
mov ah,2
int 21h
loop chuzhan
pop dx
pop cx
pop bx
pop ax
ret
dec_out3 endp
paixu proc near
MOV SI,0
MOV DI,0
LL3:
CMP DI,14
JZ LLEND
LL1:
CMP SI,14
JZ NEND
MOV BL,XU[SI]
CMP XU[SI+1],BL
JG LL2 ; 后一位大于前一位
INC SI
JMP LL1
LL2:
MOV CL,BL
MOV BL,XU[SI+1]
MOV XU[SI],BL
MOV XU[SI+1],CL ;交换
INC SI
JMP LL1
NEND:
INC DI
MOV SI,0
JMP LL3
LLEND:
RET
paixu endp
CODES ENDS
END START
- 把第一题以子程序的结构编写,用子程序实现数组的分类(正负),并编写输出子程序把原始数组、分类后的正负数组分别输出显示。
main为主程序,classify为数组分类,process为数组显示
DATAS SEGMENT
;此处输入数据段代码
array db 4 DUP(21h), 12 DUP(0ffh),4 DUP(21h)
arrayP db 20 DUP(11h)
arrayN db 20 DUP(22h)
count db ?,?
string1 db 'original array: $'
string2 db 'positive array: $'
string3 db 'negative array: $'
string4 db ' $'
CRLF DB 0AH,0DH,'$'
DATAS ENDS
STACKS SEGMENT
;此处输入堆栈段代码
STACKS ENDS
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
MOV AX,DATAS
MOV DS,AX
mov es,ax
;此处输入代码段代码
main proc ;主程序
xor ax,ax
xor bx,bx
xor cx,cx
xor dx,dx
mov dh,21d
lea si,array
lea cx,arrayP
lea bx,arrayN
cld
call classify ;分组
xor cx,cx
mov dh,20d
mov ch,ah
sub dh,ch
mov count,ah
mov count+1,dh ;记录正数和负数的个数
lea si,array
lea dx,string1
xor cx,cx
mov cx,20d
call process ;输出原数组
lea si,arrayP
lea dx,string2
xor cx,cx
mov cl,count+1
call process ;输出正数数组
lea si,arrayN
lea dx,string3
xor cx,cx
mov cl,count
call process ;输出负数数组
MOV AH,4CH
INT 21H
main endp
classify proc
again:
dec dh
JZ q
lodsb
test al,80h ;判断首位是否为1来区分正负
JNZ negative
mov di,cx
stosb
inc cx ;地址+1
jmp again
negative:
mov di,bx
stosb
inc bx ;地址+1
inc ah ;记录负数个数
jmp again
q:
ret
classify endp
process proc
;lea dx,string1
mov ah,09
int 21h
;lea si,array
cld
print:
lodsb
mov bl,al
and al,0fh ;一个数据的低位
add al,30h
cmp al,3ah
jl printit1
add al,7h
printit1: ;低位显示
mov dl,al
mov ah,2
int 21h
and bl,0f0h ;一个数据的高位
push cx
mov cl,4d
ror bl,cl
pop cx
add bl,30h
cmp bl,3ah
jl printit2
add bl,7h
printit2: ;高位显示
mov dl,bl
mov bl,2
int 21h
lea dx,string4
mov ah,09
int 21h
loop print
LEA DX,CRLF ;另取一行
MOV AH,09H
INT 21H
ret
process endp
CODES ENDS
END START
实验八:
- 把bx寄存器中的二进制数用十六进制数的形式在屏幕上显示出来。
DATAS SEGMENT
;此处输入数据段代码
count dw ?
DATAS ENDS
STACKS SEGMENT
;此处输入堆栈段代码
STACKS ENDS
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
MOV AX,DATAS
MOV DS,AX
;此处输入代码段代码
mov bx,12fdh;输入数据12fd
mov cx,4d
rotate:
mov count,cx
mov cl,4d
rol bx,cl
mov cx,count
mov al,bl
and al,0fh
add al,30h
cmp al,3ah
jl print
add al,7h
print:
mov dl,al
mov ah,2
int 21h
loop rotate
MOV AH,4CH
INT 21H
CODES ENDS
END START
- 编制程序输入一字符串,通过子程序统计每个字符出现的次数,并用16进制显示出来。
DATAS SEGMENT
;此处输入数据段代码
INPUT DB "Please input a string: ",'$'
OUTPUT DB "The result is: ",'$'
BUFFER DB 40 ;预定义20字节的空间
DB ? ;待输入完成后,自动获得输入的字符个数
DB 40 DUP(0)
CRLF DB 0AH, 0DH,'$'
count db 128 dup(0)
DATAS ENDS
STACKS SEGMENT
;此处输入堆栈段代码
STACKS ENDS
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
MOV AX,DATAS
MOV DS,AX
mov es,ax
;此处输入代码段代码
LEA DX, INPUT ;打印提示输入信息
MOV AH, 09H
INT 21H
LEA DX,BUFFER ;接收字符串
MOV AH, 0AH
INT 21H
MOV AL, BUFFER+1 ;对字符串进行处理
ADD AL, 2
MOV AH, 0
MOV SI, AX
MOV BUFFER[SI], '$'
LEA DX, CRLF ;另取一行
MOV AH, 09H
INT 21H
call print
MOV AH,4CH
INT 21H
print proc near
xor cx,cx
lea si,buffer+2 ;buffer+2为输入的字符串
cld
mov cl,ds:[buffer+1]
again:
lodsb
xor bx,bx
mov bl,al
inc ds:[count+bx]
loop again
mov bx,0
process:
cmp ds:[count+bx],0
jz r
mov dl,34d ;引号
mov ah,2
int 21h
mov dl,bl ;ascii字符
mov ah,2
int 21h
mov dl,34d ;引号
mov ah,2
int 21h
mov dl,58d ;冒号
mov ah,2
int 21h
xor ax,ax
mov al,ds:[count+bx]
push ax
and al,0f0h ;count高位
mov cl,4
ror al,cl
add al,30h
cmp al,3ah
jl s
add al,7h
s:
mov dl,al
mov ah,2
int 21h
pop ax
and al,0fh ;count高位
add al,30h
cmp al,3ah
jl p
add al,7h
p:
mov dl,al
mov ah,2
int 21h
LEA DX, CRLF ;另取一行
MOV AH, 09H
INT 21H
r:
inc bx
cmp bx,128
jz q
jmp process
q:
ret
print endp
CODES ENDS
END START
- 从键盘输入一系列字符(以回车键结束),并按字母、数字和其他字符分类计数,最后显示这三类的计数结果。
DATAS SEGMENT
;此处输入数据段代码
INPUT DB "Please input a string: ",'$'
OUTPUT DB "The result is: ",'$'
BUFFER DB 40 ;预定义20字节的空间
DB ? ;待输入完成后,自动获得输入的字符个数
DB 40 DUP(0)
CRLF DB 0AH, 0DH,'$'
count1 db 0
count2 db 0
count3 db 0
string1 db "count of rest = ",'$'
string2 db "count of number = ",'$'
string3 db "count of letter = ",'$'
DATAS ENDS
STACKS SEGMENT
;此处输入堆栈段代码
STACKS ENDS
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
MOV AX,DATAS
MOV DS,AX
mov es,ax
;此处输入代码段代码
LEA DX, INPUT ;打印提示输入信息
MOV AH, 09H
INT 21H
LEA DX,BUFFER ;接收字符串
MOV AH, 0AH
INT 21H
MOV AL, BUFFER+1 ;对字符串进行处理
ADD AL, 2
MOV AH, 0
MOV SI, AX
MOV BUFFER[SI], '$'
LEA DX, CRLF ;另取一行
MOV AH, 09H
INT 21H
xor cx,cx
lea si,buffer+2 ;buffer+2为输入的字符串
cld
mov cl,ds:[buffer+1]
inc cl
again:
dec cl
cmp cl,0
jz q
lodsb
cmp al,30h
jl l1
cmp al,3ah
jl l2
cmp al,41h
jl l1
cmp al,5bh
jl l3
cmp al,61h
jl l1
cmp al,7bh
jl l3
l1:
inc count1
jmp again
l2:
inc count2
jmp again
l3:
inc count3
jmp again
q:
xor ax,ax
LEA DX,string1
mov al,count1
call print
xor ax,ax
LEA DX,string2
mov al,count2
call print
xor ax,ax
LEA DX,string3
mov al,count3
call print
MOV AH,4CH
INT 21H
print proc near
push ax
;LEA DX, string1
MOV AH, 09H
INT 21H
and al,0f0h ;count高位
mov cl,4
ror al,cl
add al,30h
cmp al,3ah
jl s
add al,7h
s:
mov dl,al
mov ah,2
int 21h
pop ax
and al,0fh ;count低位
add al,30h
cmp al,3ah
jl p
add al,7h
p:
mov dl,al
mov ah,2
int 21h
;mov dl,count1
;mov ah,2
;int 21h
LEA DX, CRLF ;另取一行
MOV AH, 09H
INT 21H
ret
print endp
CODES ENDS
END START
- 有一个首地址为data的100个字的数组,试编程序删除数组中所有为零的项,并将后续项向前移,最后将数组的剩余部分补上零。
将不为0的数据放入tmp数组中,最后一次放回data并在末尾补零。
30个数据0,70个数据不为0,程序运行后数组最后30项为0:
DATAS SEGMENT
;此处输入数据段代码
data DW 5 DUP(0), 25 DUP(1122h), 5 DUP(0), 25 DUP(0ffh), 20 DUP(0), 20 DUP(22h)
tmp DW 100 DUP(0)
count db 0
DATAS ENDS
STACKS SEGMENT
;此处输入堆栈段代码
STACKS ENDS
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
MOV AX,DATAS
MOV DS,AX
mov es,ax
;此处输入代码段代码
lea si,data
lea di,tmp
cld
mov cx,100d
loop1: ;将不为零的数据依次存入tmp中
lodsw
cmp ax,0
jz r
stosw
inc count
r:
loop loop1
lea si,tmp
lea di,data
cld
xor cx,cx
mov cl,count ;有count个数据不为零
loop2: ;将tmp中数据依次存回data中
lodsw
stosw
loop loop2
mov ax,0 ;最后100-count个位置补零
loop3:
stosw
inc count
cmp count,100d
jnz loop3
MOV AH,4CH
INT 21H
CODES ENDS
END START