冒泡排序等几个汇编程序
1. 冒泡排序
冒泡排序
DATA SEGMENT WORD PUBLIC 'DATA'
ORG 00H
ARRAY_SIZE DW 5 ;待排序的数的个数
NUMBER_ARRAY DW 100D, 64D, 79D, 22D, 113D ;待排序的数
PRIVIOUS DW 00H ;用来存放冒牌排序中比较时的数
LAST DW 00H ;用来存放冒牌排序中比较时的数
TEN DB 10 ;数字10, 用于分解一个数
DATA ENDS
EXTRA SEGMENT WORD PUBLIC 'EXTRA'
EXTRA ENDS
CODE SEGMENT WORD PUBLIC 'CODE'
INITIIALIZE PROC ;用来初始化段寄存器的过程
MOV AX, EXTRA
MOV ES, AX
MOV AX, DATA
MOV DS, AX
RET
INITIIALIZE ENDP
TERMINATE PROC ;用来退出程序的过程
MOV AH, 4CH
INT 21H ;因为程序直接退出, 可以不需要加RET
RET
TERMINATE ENDP
PRINTLN PROC ;换行的过程
PUSH AX
PUSH DX ;过程中要用到这两个寄存器, 先把原来的值存到栈里
MOV AH, 2 ;功能号2是字符显示
MOV DL, 0DH ;DL寄存器存放打印字符, 这里是0D是换行的意思
INT 21H ;中断操作, 进行打印字符
MOV DL, 0AH ;0A是光标指向第一个字符的意思
INT 21H ;中断操作
POP DX
POP AX ;将原来的值再放回对应的寄存器
RET ;过程结束, 返回
PRINTLN ENDP
PRINT_ARRAY PROC ;打印输出排序的数字
; 算法: 将一个数字逐一与10相除, 余数入栈, 商继续除以10, 直到商为0, 此时将栈中的元素逐一出栈, 则可以得到这个数字每一位的数, 再+48可以得到每一位的字符数字, 再输出即可看到这个数字被打印出来了
; 因为直接输出这个数, 会输出这个数的ASCII码, 不是我们想要的值, 所以要注意分解位数, 再+48输出
PUSH AX
PUSH BX
PUSH CX
PUSH DX
MOV DI, OFFSET ARRAY_SIZE ;获取内存中这组数字的第一个数的偏移地址
MOV CX, [DI] ;将偏移地址放入CX寄存器
MOV SI, OFFSET NUMBER_ARRAY ;获取内存中存放这组数字长度的位置的偏移地址
MOV BX, 0
AGAIN:
MOV AX, [BX+SI] ;将第一个数字的值放入AX中, 采用基址间址寻址
PUSH CX ;下面要用到CX寄存器, 先将之前的内容入栈, 用完后再出栈即可恢复原来的功能
PUSH BX ;下面要用到BX寄存器
XOR CX, CX ;CX置零
DIVISION:
IDIV [TEN]
XOR BX, BX
MOV BL, AH
ADD BL, 48
PUSH BX
MOV AH, 0
INC CX
CMP AX, 0
JNE DIVISION
OUTPUT:
XOR AX, AX
POP AX
MOV DX, AX
MOV AH, 2
INT 21H
LOOP OUTPUT
MOV DL, ' '
INT 21H
POP BX
ADD BX, 2
POP CX
LOOP AGAIN
POP DX
POP CX
POP BX
POP AX
RET
PRINT_ARRAY ENDP
ASSUME CS:CODE, ES:EXTRA, DS:DATA
START:
CALL INITIIALIZE
CALL PRINT_ARRAY
MOV SI, OFFSET ARRAY_SIZE
SUB [SI], 1
MOV AX, 0 ;AX记录外循环次数
I:
XOR DX, DX
MOV DX, [SI]
DEC DX
SUB DX, AX
MOV BX, DX ;BX记录内循环总次数
MOV CX, 0 ;CX记录内循环次数
XOR DX, DX
J:
CMP CX, BX
JE ENDJ
PUSH BX
;BX = CX * 2
MOV BX, CX
SAL BX, 1
MOV SI, OFFSET NUMBER_ARRAY
MOV DX, [BX+SI]
MOV SI, OFFSET PRIVIOUS
MOV [SI], DX
;BX = BX + 2
ADD BX, 2
MOV SI, OFFSET NUMBER_ARRAY
MOV DX, [BX+SI]
MOV SI, OFFSET LAST
MOV [SI], DX
CMP [PRIVIOUS], DX
;前 > 后
JB SWPA
SUB BX, 2
MOV SI, OFFSET NUMBER_ARRAY
XCHG [BX+SI], DX
ADD BX, 2
MOV SI, OFFSET NUMBER_ARRAY
MOV [BX+SI], DX
SWPA:
POP BX
INC CX
MOV SI, OFFSET ARRAY_SIZE
CMP CX, BX
JMP J
ENDJ:
INC AX
CMP AX, [SI]
JNE I
MOV SI, OFFSET ARRAY_SIZE
ADD [SI], 1
CALL PRINTLN
CALL PRINT_ARRAY
CALL TERMINATE
CODE ENDS
END START
2. 从键盘输入一个字符串,并输出该字符串
DATA SEGMENT WORD PUBLIC 'DATA'
ORG 00H
STRING_BUFFER DB 50, 0, 50 DUP (00h) ;字符串缓冲区
DATA ENDS
EXTRA SEGMENT WORD PUBLIC 'EXTRA'
EXTRA ENDS
CODE SEGMENT WORD PUBLIC 'CODE'
INITIIALIZE PROC ;用来初始化段寄存器的过程
MOV AX, EXTRA
MOV ES, AX
MOV AX, DATA
MOV DS, AX
RET
INITIIALIZE ENDP
TERMINATE PROC ;用来退出程序的过程
MOV AH, 4CH
INT 21H ;因为程序直接退出, 可以不需要加RET
RET
TERMINATE ENDP
PRINTLN PROC ;换行的过程
PUSH AX
PUSH DX ;过程中要用到这两个寄存器, 先把原来的值存到栈里
MOV AH, 2 ;功能号2是字符显示
MOV DL, 0DH ;DL寄存器存放打印字符, 这里是0D是换行的意思
INT 21H ;中断操作, 进行打印字符
MOV DL, 0AH ;0A是光标指向第一个字符的意思
INT 21H ;中断操作
POP DX
POP AX ;将原来的值再放回对应的寄存器
RET ;过程结束, 返回
PRINTLN ENDP
INPUT_STRING MACRO STRING_BUFFER_ADDRESS ;字符串输入过程
PUSH DX
PUSH AX
MOV DX, OFFSET STRING_BUFFER_ADDRESS ;字符串缓冲区的偏移地址放到DX寄存器
MOV AH, 0AH ;功能号是0AH表示字符串输入
INT 21H ;中断操作, 输入字符串
CALL PRINTLN ;输入结束, 调用换行过程
POP AX
POP DX
ENDM
OUTPUT_STRING MACRO STRING_BUFFER ;字符串输出过程
PUSH CX
PUSH BX
PUSH DX
PUSH AX
XOR CX, CX ;清空CX值
MOV BX, OFFSET STRING_BUFFER ;获取字符串缓冲区首地址
MOV CL, BYTE PTR [BX+1] ;获取字符串长度, 存入CL
ADD BX, 2 ;BX = BX + 2
ADD BL, CL ;BL = BL + 2
MOV BYTE PTR[BX], 0DH ;将换行符存入偏移地址为BX内容的内存
INC BX ;BX = BX + 1
MOV BYTE PTR[BX], 0AH ;将0AH符存入偏移地址为BX内容的内存
INC BX
MOV BYTE PTR[BX], '$' ;结尾放入$
MOV DX, OFFSET STRING_BUFFER ;将字符串缓冲区地址放入DX
ADD DX, 2 ;DX指向输入内容的第一个位置
MOV AH, 09H ;DOS软中断, 09H表示字符串显示
INT 21H ;中断
POP AX
POP DX
POP BX
POP CX
ENDM
ASSUME CS:CODE, ES:EXTRA, DS:DATA
START:
CALL INITIIALIZE ;调用初始化过程
STRING_BUFFER_ADDRESS = STRING_BUFFER ;获取内容地址
INPUT_STRING STRING_BUFFER_ADDRESS ;输入字符串
OUTPUT_STRING STRING_BUFFER ;显示字符串
CALL TERMINATE
CODE ENDS
END START
结果
3. 从键盘输入一个2个数字, 将它转变为一个十位数, 并再转换为字符, 输出
DATA SEGMENT WORD PUBLIC 'DATA'
ORG 00H
TEN DB 10D
SUM DB 00H
DATA ENDS
STACK SEGMENT WORD PUBLIC 'STACK'
STACK ENDS
CODE SEGMENT WORD PUBLIC 'CODE'
INITIIALIZE PROC ;用来初始化段寄存器的过程
MOV AX, STACK
MOV SS, AX
MOV AX, DATA
MOV DS, AX
RET
INITIIALIZE ENDP
TERMINATE PROC ;用来退出程序的过程
MOV AH, 4CH
INT 21H ;因为程序直接退出, 可以不需要加RET
RET
TERMINATE ENDP
PRINTLN PROC ;换行的过程
PUSH AX
PUSH DX ;过程中要用到这两个寄存器, 先把原来的值存到栈里
MOV AH, 2 ;功能号2是字符显示
MOV DL, 0DH ;DL寄存器存放打印字符, 这里是0D是换行的意思
INT 21H ;中断操作, 进行打印字符
MOV DL, 0AH ;0A是光标指向第一个字符的意思
INT 21H ;中断操作
POP DX
POP AX ;将原来的值再放回对应的寄存器
RET ;过程结束, 返回
PRINTLN ENDP
NUMBER_OUTPUT MACRO NUMBER_ADDRESS
PUSH AX
PUSH BX
PUSH CX
PUSH DX
MOV AX, [NUMBER_ADDRESS]
XOR CX, CX
DIVISION:
IDIV [TEN]
XOR BX, BX
MOV BL, AH
ADD BL, 48
PUSH BX
MOV AH, 0
INC CX
CMP AX, 0
JNE DIVISION
OUTPUT:
XOR AX, AX
POP AX
MOV DX, AX
MOV AH, 2
INT 21H
LOOP OUTPUT
POP DX
POP CX
POP BX
POP AX
ENDM
ASSUME CS:CODE, SS:STACK, DS:DATA
START:
CALL INITIIALIZE
;输入数字字符转变为数值存入栈
XOR CX, CX
XOR DX, DX
MOV CX, 0
CMP CX, 1 ;ZF = 0
AGAIN: ;输入
MOV AH, 1
INT 21H
SUB AL, 48
MOV AH, 0
PUSH AX
INC CX
CMP CX, 2 ;输入字符的个数, 2表示输入两字符
JNE AGAIN
;将栈中的数值整体变成一个数值
MOV DX, CX
XOR BX, BX
XOR CX, CX
A:
POP AX
MOV BX, CX
XOR CX, CX
CMP CX, 0
B:
CMP CX, BX
JE DOWN ;CX == BX
MUL [TEN]
INC CX
JMP B
DOWN:
PUSH BX
MOV BX, OFFSET SUM
ADD [BX], AX
POP BX
INC CX
CMP CX, DX
JE SHUT ;CX == DX
JMP A
SHUT:
CALL PRINTLN
LEA SI, SUM
;将数值转变为数字字符并输出
NUMBER_OUTPUT SI
CALL TERMINATE
CODE ENDS
END START
结果
4. 从键盘输入5个十以内的数(不包括10),求和并输出
DATA SEGMENT WORD PUBLIC 'DATA'
ORG 00H
TEN DB 10D
SUM DB 00H
DATA ENDS
STACK SEGMENT WORD PUBLIC 'STACK'
STACK ENDS
CODE SEGMENT WORD PUBLIC 'CODE'
INITIIALIZE PROC ;用来初始化段寄存器的过程
MOV AX, STACK
MOV SS, AX
MOV AX, DATA
MOV DS, AX
RET
INITIIALIZE ENDP
TERMINATE PROC ;用来退出程序的过程
MOV AH, 4CH
INT 21H ;因为程序直接退出, 可以不需要加RET
RET
TERMINATE ENDP
PRINTLN PROC ;换行的过程
PUSH AX
PUSH DX ;过程中要用到这两个寄存器, 先把原来的值存到栈里
MOV AH, 2 ;功能号2是字符显示
MOV DL, 0DH ;DL寄存器存放打印字符, 这里是0D是换行的意思
INT 21H ;中断操作, 进行打印字符
MOV DL, 0AH ;0A是光标指向第一个字符的意思
INT 21H ;中断操作
POP DX
POP AX ;将原来的值再放回对应的寄存器
RET ;过程结束, 返回
PRINTLN ENDP
NUMBER_OUTPUT MACRO NUMBER_ADDRESS
PUSH AX
PUSH BX
PUSH CX
PUSH DX
MOV AX, [NUMBER_ADDRESS]
XOR CX, CX
DIVISION:
IDIV [TEN]
XOR BX, BX
MOV BL, AH
ADD BL, 48
PUSH BX
MOV AH, 0
INC CX
CMP AX, 0
JNE DIVISION
OUTPUT:
XOR AX, AX
POP AX
MOV DX, AX
MOV AH, 2
INT 21H
LOOP OUTPUT
POP DX
POP CX
POP BX
POP AX
ENDM
ASSUME CS:CODE, SS:STACK, DS:DATA
START:
CALL INITIIALIZE
;输入数字字符转变为数值存入栈
XOR CX, CX
XOR DX, DX
MOV CX, 0
CMP CX, 1 ;ZF = 0
AGAIN: ;输入
MOV AH, 1
INT 21H
SUB AL, 48
MOV AH, 0
PUSH AX
INC CX
CMP CX, 5
JNE AGAIN
;将栈中的数值相加变成一个数值
XOR AX, AX
XOR DX, DX
LEA SI, SUM
ACC:
POP DX
ADD [SI], DX
LOOP ACC
CALL PRINTLN
;将数值转变为数字字符并输出
NUMBER_OUTPUT SI
CALL TERMINATE
CODE ENDS
END START
结果
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/122844.html