汇编是真的很难啊,我哭死,写的我头疼,给老师演示的时候感觉我左脑是水,右脑是面粉,摇一摇就满脑子的浆糊了。垃圾代码如下,如有问题,欢迎指出~
对以下数组10,267,9,0,68,-516,3,85,OFCH,101,-32
1)计算数组中正数累加结果保存到变量result。
2)计算数组到负数为止的非负数累加结果保存到变量。
3)计算数组中零,正,负数,奇,偶数元素个数分别保存。
4)查找数组中最小元素,绝对值最大元素,排序数组。要求菜单提示选择,调试查看运行结果。
代码如下
.MODEL SMALL
.STACK 4096
.DATA
ARRAY DW 10,267,9,0,68,-516,3,85,101,-32,0FCH;数组的内容
RESULT DW 0 ;计算正数之和
SUM DW 0 ;计算数组到负数为止的非负数累加结果保存到变量SUM
NUMZERO DB 0 ;0的个数
NUMFUSHU DB 0 ;负数个数
NUMZHENG DB 0 ;正数个数
NUMJISHU DB 0 ;奇数个数
NUMOUSHU DB 0 ;偶数个数
MINNUM DW 0 ;最小的元素
MAXNUM DW 0 ;绝对值最大的元素
STRING0 DB 0DH,0AH,'Please input a number:',0DH,0AH,'$'
STRING1 DB 0DH,0AH,'If you input 1,we will add zhengshu.','$'
STRING2 DB 0DH,0AH,'If you input 2,we will add zhenshu till a fushu.','$'
STRING3 DB 0DH,0AH,'If you input 3,we will count the number of zhengshu,fushu,zero,jishu and oushu','$'
STRING4 DB 0DH,0AH,'If you input 4,we will seek the smallest num and the biggest num ,then paixu.','$'
STRING5 DB 0DH,0AH,'We add the sum in RESULT!',0DH,0AH,'$'
STRING6 DB 0DH,0AH,'We add this numbers in SUM!',0DH,0AH,'$'
STRING7 DB 0DH,0AH,'Counting positive and negative numbers has ended!','$'
STRING8 DB 0DH,0AH,'The counting of odd even numbers has ended!',0DH,0AH,'$'
STRING9 DB 0DH,0AH,'The number of jishu is:',0DH,0AH,'$'
STRING10 DB 'The number of oushu is:',0DH,0AH,'$'
STRING11 DB 0DH,0AH,'The number of zhengshu is:',0DH,0AH,'$'
STRING12 DB 0DH,0AH,'The number of fushu is:',0DH,0AH,'$'
STRING13 DB 0DH,0AH,'The number of 0 is:',0DH,0AH,'$'
STRING14 DB 0DH,0AH,'SORT SUCCESS!',0DH,0AH,'$'
.CODE
MAIN PROC FAR
MOV AX,@DATA
MOV DS,AX
;-----------------------
;输出一串提示
LEA DX,STRING1
MOV AH,09H
INT 21H
LEA DX,STRING2
MOV AH,09H
INT 21H
LEA DX,STRING3
MOV AH,09H
INT 21H
LEA DX,STRING4
MOV AH,09H
INT 21H
LEA DX,STRING0
MOV AH,09H
INT 21H;输出一串提示
MOV AH,1
INT 21H;键盘输入并回显
MOV DL,AL;输入的数字在AL中,赋值给DL
CMP DL,'1';判断是否为1
JE HANSHU1;如果是1就进入函数1
MOV DL,AL;输入的数字在AL中,赋值给DL
CMP DL,'2';判断是否为2
JE HANSHU2;如果是2就进入函数2
MOV DL,AL;输入的数字在AL中,赋值给DL
CMP DL,'3';判断是否为3
JE HANSHU3;如果是3就进入函数3
MOV DL,AL;输入的数字在AL中,赋值给DL
CMP DL,'4';判断是否为4
JE HANSHU4;如果是4就进入函数4
MOV AH,4CH;返回MOS-DOS窗口
INT 21H
MAIN ENDP
;函数1-----计算正数之和
HANSHU1 PROC NEAR
LEA DX,STRING5
MOV AH,09H
INT 21H;输出一串提示,开始计算RESULT
MOV CX,LENGTHOF ARRAY ;数组的长度
MOV SI,OFFSET ARRAY ;偏移量
MOV AX,0 ;计算AX,初始化为0
MOV BX,0 ;先存在BX里面
LP:
MOV AX,[SI] ;让[SI]中的数的符号位和1000 0000B相与,如果结果不是0,那么代表是负数,反之,正数
CMP AX,8000H
JA NEXT
ADD BX,AX
NEXT:
ADD SI,TYPE ARRAY ;每次增加偏移量
LOOP LP
MOV RESULT,BX ;把AX中的值赋值给RESULT
mov ax,bx
CALL OUTPUT1
CALL MAIN
RET
HANSHU1 ENDP
;函数2-----计算数组到负数为止的非负数累加结果保存到变量SUM
HANSHU2 PROC NEAR
LEA DX,STRING6
MOV AH,09H
INT 21H;输出一串提示,开始计算SUM
MOV CX,LENGTHOF ARRAY ;数组的长度
MOV SI,OFFSET ARRAY ;偏移量
MOV AX,0 ;计算AX,初始化为0
MOV BX,0 ;结果先放在BX里面
LP:
MOV AX,[SI] ;让[SI]中的数的符号位和1000 0000B相与,如果结果不是0,那么代表是负数,反之,正数=0
CMP AX,8000H
JA NEXT ;结果不为0跳转,即负数跳转
ADD BX,AX
MOV SUM,BX
ADD SI,TYPE ARRAY ;每次增加偏移量
LOOP LP
NEXT:
mov ax,bx
CALL OUTPUT1
CALL MAIN
RET
HANSHU2 ENDP
;函数3--------计算数组中零,正,负数,奇,偶数元素个数分别保存。
HANSHU3 PROC NEAR
LEA DX,STRING7
MOV AH,09H
INT 21H ;输出一串提示,开始计算NUMZERO,NUMFUSHU,NUMZHENG
MOV SI,OFFSET ARRAY ;偏移量
MOV CX,LENGTHOF ARRAY ;用于计数,总共11个
FIRST: ;比较计数板块
CMP CX,0 ;比较次数是否达到最后了
JE OUTPUT ;相等的时候跳转到输出板块
MOV AX,[SI] ;接收数据
CMP AX,0 ;先判断是否是零
JE ZERONUM ;表示为零
TEST AX,8000H
JZ PNUM ;等于0的时候跳转
JA NNUM ;无符号大于跳转
ZERONUM:
ADD NUMZERO,1
JMP OVER;每一次输出收尾
NNUM:
ADD NUMFUSHU,1
JMP OVER
PNUM:
ADD NUMZHENG,1
JMP OVER
OVER:
DEC CX;计数
ADD SI,2;偏移量
JMP FIRST;回到起点
OUTPUT:;输出板块bx/cx不能动,保留着计数
LEA DX, string11;正数的输入提示
MOV AH, 09H
INT 21H
ADD NUMZHENG,30H
MOV DL,NUMZHENG
MOV AH,2
INT 21H
LEA DX, string12;负数的输入提示
MOV AH, 09H
INT 21H
ADD NUMFUSHU,30H
MOV DL,NUMFUSHU
MOV AH,2
INT 21H
LEA DX, string13;零的输入提示
MOV AH, 09H
INT 21H
ADD NUMZERO,30H
MOV DL,NUMZERO
MOV AH,2
INT 21H
CALL NUM
RET
HANSHU3 ENDP
;函数3里面的一个函数-------计算奇数偶数元素的个数
NUM PROC NEAR
LEA DX,STRING8
MOV AH,09H
INT 21H;输出一串提示,开始计算NUMJISHU,NUMOUSHU
MOV BX,OFFSET ARRAY ;BX和SI都可以做偏移量
MOV DX,0 ;DX=0
MOV CX,LENGTHOF ARRAY ;CX是数组的长度
NEXT:
MOV AX,[BX]
TEST AX,1 ;判断奇数偶数,最后一位为0是偶数,最后一位是1是奇数
JNZ L1 ;ZF不等于0就跳转,即奇数跳转
INC DL ;DL+1
JMP L2 ;ZF=0,即偶数跳转
L1:;奇数
INC DH ;DH+1,奇数个数存在DH里面,偶数个数存在DL里面
L2:;偶数
ADD BX,TYPE ARRAY
LOOP NEXT
MOV BX,DX ;DX=BX--->DL=BL,DH=BH
;输出奇数的个数
MOV DX,OFFSET STRING9
MOV AH,09H
INT 21H
MOV DL,BH
ADD DL,30H
MOV AH,2H
INT 21H
;换行符
MOV DL,0DH
MOV AH,02H
INT 21H
;回车符
MOV DL,0AH
MOV AH,2H
INT 21H
;输出偶数的个数
MOV DX,OFFSET STRING10
MOV AH,09H
INT 21H
MOV DL,BL
ADD DL,30H
MOV AH,2H
INT 21H
CALL MAIN
RET
NUM ENDP
;函数4--------查找最小元素,绝对值最大元素和数组排序
HANSHU4 PROC NEAR
LEA DX,STRING4
MOV AH,09H
INT 21H ;输出一串提示,开始计算MINNUM,MAXNUM
MOV BX,OFFSET ARRAY ; 设置指向数据区的指针
MOV AX,[BX];
MOV MAXNUM,AX ; 最大最小值都初始化成第1个数
MOV MINNUM,AX
MOV CL,LENGTHOF ARRAY ; 数据个数
A1:
MOV AX,[BX] ; 从内存取数
CMP AX,MAXNUM ; 大于最大值MAX转去替换MAX
JG A2
CMP AX,MINNUM
JL A3 ; 小于最小MIN转去替换MIN
JMP A4
A2:
MOV MAXNUM,AX
JMP A4
A3:
MOV MINNUM,AX
A4: INC BX
LOOP A1
MOV AX,MAXNUM
ADD AX,MINNUM
TEST AX,8000H
JA CHANGE
CHANGE:
MOV BX,MINNUM
NEG BX
MOV MAXNUM,BX
CALL PAIXU
RET
HANSHU4 ENDP
;函数PAIXU,是函数4里面的一个子函数,用来冒泡排序的
PAIXU PROC NEAR
LEA DX,STRING14
MOV AH,09H
INT 21H
LEA DI, ARRAY
MOV BL,LENGTHOF ARRAY
NEXT1:
MOV SI,DI
MOV CL,BL
NEXT2:
MOV AX,[SI]
INC SI
INC SI
CMP AX,[SI]
Jc NEXT3 ;小于则不交换
MOV DX,[SI]
MOV [SI-2],DX
MOV [SI],AX
NEXT3:
DEC CL
JNZ NEXT2
DEC BL
JNZ NEXT1
CALL MAIN
RET
PAIXU ENDP
;多位输出函数
OUTPUT1 proc near
;初始化变量
mov cl,10;作为除数
mov ch,0;用于计数便于后续出栈输出
divagain:;除法数字剥离部分
cmp ax,0;判断是否已经除尽
je divover
inc ch;计数器加1
div cl
push ax;入栈,提取的时候取用ah部分,存储余数(低位优先)
mov ah,0;调整ax
jmp divagain;再次除法剥离数字
divover:;出栈输出部分
cmp ch,0;判断数字是否已经出尽
je outputover
pop ax;取用ah部分
mov dl,ah;输出部分
add dl,30H
mov ah,2
int 21h
dec ch
jmp divover
outputover:
ret
OUTPUT1 endp
END
效果如下
对于100以内的整数判断是否是素数,如果是素数,十进制形式输出,每行输出10个数。
data segment
text DB 'Prime numbers within 100 are:',0DH,0AH,'$'
var1 DB 0,4 dup(0)
data ends
assume cs:code,ds:data
code segment
start:
mov ax,data
mov ds,ax
mov dx,OFFSET text
MOV AH,9H
INT 21H
mov cx,99
aa1: ;第一层循环
mov ax,101
sub ax,cx
push cx
call demo1 ;判断ax是否为素数
pop cx
loop aa1
demo1 proc ;判断ax是否为素数
mov cx,ax ;ax=2,
dec cx ;自减指令,cx=1
aa2: ;第二层循环
push ax
div cl ;ax%cl=ah
cmp ah,0
pop ax
je aa2end ;if(i%j==0)break
loop aa2
aa2end:
cmp cx,1
jne demo1end
mov ah,0
mov dx,ax
call demo2 ;输出多位数
demo1end:
ret
demo1 endp
demo2 proc ;输出多位数
push dx
;mov dx,1060
mov ax,dx
mov dx,0
;mov var1,0
again:
mov bx,10
div bx
inc var1[0]
mov bl,var1
mov bh,0
mov var1[bx],dl
mov dx,0
cmp ax,0
jne again
again1:
mov bl,var1
mov bh,0
mov dl,var1[bx]
add dl,30h
mov ah,2
int 21h
dec var1
mov al,var1
cmp al,0
jne again1
mov dl,9H ;制表符
mov ah,2
int 21h
pop dx
ret
demo2 endp
code ends
end start
效果如下
计算输入两个数的最小公倍数和最大公约数
代码如下
;计算输入两个数的最小公倍数和最大公约数
.MODEL SMALL
.DATA
NUMBER1 DW ?
NUMBER2 DW ?
BIGANS DW ? ;最大公约数
SMALLANS DW ? ;最小公倍数
INPUT1 DB 'input number1=$'
INPUT2 DB 0dh,0ah,'input number2=$'
BIGOUTPUT DB 0DH,0AH,'BIGANS=$' ;最大公约数
SMALLOUTPUT DB 0DH,0AH,'SMALLANS=$' ;最小公倍数
.CODE
MAIN PROC FAR
MOV AX,@DATA
MOV DS,AX
;-----------------------以上是模板
;获取第一个数
LEA DX,INPUT1
MOV AH,9
INT 21H
CALL SHURU ;打开输入
MOV NUMBER1,BX ;把BX中的值赋值给X
;获取第二个数
LEA DX,INPUT2
MOV AH,9
INT 21H
CALL SHURU
MOV NUMBER2, BX
CALL GONGYUESHU
MOV BX, BIGANS
LEA DX,BIGOUTPUT
MOV AH,9
INT 21H
CALL XIANSHI
CALL GONGBEISHU
MOV BX,SMALLANS
LEA DX,SMALLOUTPUT
MOV AH,9
INT 21H
CALL XIANSHI
MOV AH, 4CH
INT 21H
MAIN ENDP
;输入数字到BX
SHURU PROC NEAR
MOV BX,0 ;初始化BX为0
S1:
MOV AH,1 ;键盘输入并回显
INT 21H
CMP AL, 0DH ;输入是回车是结束
JZ EXIT ;标志位为0就跳转
AND AX, 000FH
XCHG AX, BX ;将AX和BX中的内容交换
MOV CX, 10 ;初始化CX=10
MUL CX ;之前输入的数乘以10 加上新输得数..比如123先是 0*10+1 ->1*10+2 ->12*10+3
ADD BX, AX ;把AX和BX相加存入BX中
JMP S1 ;继续输入
EXIT: ;输入了回车 退出
;MOV DL, 0AH ;换行
MOV AH, 2 ;显示输入字符
INT 21H
RET
SHURU ENDP
;显示BX中的数
XIANSHI PROC NEAR
;MOV DL, 0AH ;换行
;MOV AH, 2
;INT 21H
MOV AX, BX ;将BX中的值给X
MOV BX, 10 ;给BX赋值成10
MOV CX, 0 ;给CX赋值成0
LET1: ;将要显示的数除以10 把余数入栈
MOV DX, 0 ;DX赋值成10
INC CX ;CX+1
IDIV BX ;除以BX,除数为16位,则被除数为32位,商放在AX,余数放在DX
PUSH DX ;余数入栈
CMP AX, 0 ;商为0时结束
JNZ LET1
LET2:
POP AX ;将商弹入 AX
ADD AX, 3030H ;商调整为ASC码
MOV DL, AL ;显示商
MOV AH, 2
INT 21H
LOOP LET2
RET
XIANSHI ENDP
;求两个数的最大公约数其中BX是除数
GONGYUESHU PROC NEAR
MOV BX, 1 ;BX初始化为1
SS1:
MOV DX, 0 ;DX初始化为0
MOV AX, NUMBER1 ;把其中一个数赋值给AX
DIV BX ;除以BX,商在AX,余数在DX
CMP DX, 0 ;余数和0比较
JNZ SS2 ;如果BX不能被整除 BX不是公约数 跳到SS2
MOV DX, 0 ;DX赋值给0
MOV AX, NUMBER2 ;AX赋值另一个数
DIV BX ;这个数也除以BX
CMP DX, 0 ;余数和0比较
JNZ SS2 ;如果BX不能被Y整除 BX不是公约数 跳到SS2
MOV BIGANS,BX ;如果既能被X整除又能被Y整除的值放到ans里面
SS2: ;BX加到等于被除数的时候跳出 ..否则除数加1..判断BX+1是不是公约数..
CMP BX,NUMBER1 ;BX和第一个数比较
INC BX ;BX+1
JNZ SS1 ;如果BX!=这个数,就跳转
RET
GONGYUESHU ENDP
;最小公倍数就是X乘Y在除以最大公约数...
GONGBEISHU PROC NEAR
MOV AX, NUMBER1 ;将第一个数赋值给AX
MUL NUMBER2 ;乘以第二个数
DIV BIGANS ;除以最大公约数,商在AX
MOV SMALLANS,AX ;把商赋值给最小公倍数
RET
GONGBEISHU ENDP
END
效果如下
查找子串在字符串中出现的次数并去除
代码如下
.MODEL SMALL
.DATA
;单词初始化只给8个字节
WORD_LEN DB 8
FACTWORD_LEN DB ?
KEY_WORD DB 8 DUP(?)
;句子给32个字节
SENTENCE_LEN DB 32
FACTSENTENCE_LEN DB ?
SENTENCES DB 32 DUP(?)
;输入的信息
INPUT1 DB 'Enter the Keyword:$'
INPUT2 DB 'Enter the Sentence:$'
;输出的信息
OUTPUT1 DB 'The number is:$'
OUTPUT2 DB 'After that,the sentence is:$'
OUTPUT DB 'No Match!$'
NUM DB 0
STRING DB ' '
.CODE
MAIN PROC NEAR
MOV AX,@DATA
MOV DS,AX
;------------模板
MOV ES,AX
BEGIN:
;输出信息
MOV AH,09H
LEA DX,INPUT2
INT 21H
MOV AH,0AH
LEA DX,SENTENCE_LEN
INT 21H
CALL NEWLINE
MOV AH,9H
LEA DX,INPUT1
INT 21H
MOV AH,0AH ;输入到缓冲
LEA DX,WORD_LEN
INT 21H
CALL NEWLINE
MOV CH,FACTSENTENCE_LEN
MOV CL,FACTWORD_LEN
LEA DI,SENTENCES ;输入的句子在DI中
MOV BH,0 ;BH=0
ZBJ:
LEA SI,KEY_WORD ;单词放在SI中
CMP CH,FACTWORD_LEN;正常情况下是ZF=0,CF=0
JB LOOP3 ;无符号小于则跳转,即句子的长度如果小于单词的长度,最后输出没有匹配
MOV CL,FACTWORD_LEN ;CL赋值单词实际的长度
MOV BL,0 ;BL=0
ISSAME:
CMPSB ;把单词的第一个赋值给句子的第一个
;也就是说,当单词这一位和句子的这一位不同,ZF=1
JZ LOOP1 ;ZF=0跳转
JNZ LOOP2 ;ZF=1跳转,单词和句子不匹配
LOOP1:
MOV BL,1 ;BL=1
DEC CH ;CH--,句子长度-1
DEC CL ;CL--,单词长度-1
JNZ ISSAME ;ZF=1跳转,
MOV CL,FACTWORD_LEN
ADD CL,CH
MOV DL,SENTENCE_len
mov cl,FACTWORD_LEN
add cl,ch
mov dl,FACTSENTENCE_LEN
sub dl,cl
;inc dl
MOV SI,DI
MOV CL,FACTWORD_LEN
n:
MOV AL,'-'
MOV [SI-1],AL
MOV DL,[SI-1]
DEC Cl
DEC SI
CMP Cl,0
JNZ N
ADD NUM,1
MOV BH,1
JMP ZBJ
LOOP2:
CMP BL,1 ;BL和1比较,小于就是ZF=0
JZ PJ ;标志符为0就跳转
DEC CH ;CH--
JMP ZBJ
PJ:
DEC DI ;句子的位置减一
JMP ZBJ ;跳转
loop3:
CMP BH,1 ;BH=0-->ZF=0
JZ QUIT ;ZF=0就跳转
MOV AH,09H ;输出没有匹配到
LEA DX,OUTPUT
INT 21H
CALL NEWLINE ;空一行
QUIT:
MOV AH,09H
LEA DX,OUTPUT1
INT 21H
MOV DL,NUM
ADD DL,30H
MOV AH,02H
INT 21H
CALL PRESENT
;MOV AH,4CH
;INT 21H
MAIN ENDP
;进入下一行再开始
NEWLINE PROC NEAR
MOV DL,0DH
MOV AH,02H
INT 21H
MOV DL,0AH
MOV AH,02H
INT 21H
RET
NEWLINE ENDP
PRESENT PROC NEAR
CALL NEWLINE
MOV AH,09H
LEA DX,OUTPUT2
INT 21H
MOV CL,0
LEA SI,SENTENCES
M:
MOV AL,[SI]
CMP AL,'-'
JZ X
MOV DL,[SI]
MOV AH,02H
INT 21H
INC SI
Inc CL
MOV BH,FACTSENTENCE_LEN
CMP CL,BH
JNZ M
JZ EX
X:
INC SI
Inc CL
JMP M
EX:
MOV AH,4CH
INT 21H
RET
PRESENT ENDP
END
效果如下