【8086汇编】输入任意数量的无符号整数,并使用冒泡排序进行排序后输出

不知道为啥,使用dosbox运行后,输出结果正确,但是调用4ch,退出程序时,没有退出。

data segment
buf db ?                                         ; buf 用来保存输入的数字(字符串),无符号数,无法输入负数
db ?
db 10 dup(?)

array dw 100 dup(?)                                 ; array 用来保存输入的数字
number dw 1 dup(?)                                      ; number 用来保存输入的数字个数,初始化为0
data ends
 
code segment
	assume ds:data, cs:code
	
main:
	;mov ax, data
	;mov ds, ax
	
	mov [number], 0
	
INPUT:
	lea dx, buf                                  ; 输入字符串,到buf中
	mov ah, 0ah
	int 21h
	
	mov dl, 13   ; 打印换行
	mov ah, 02h
	int 21h
	mov dl, 0ah
	mov ah, 02h
	int 21h
	
	
	
	mov bl, 13                                   ; 13 = '\r',如果输入换行,表明输入结束
	cmp [buf+2], bl
	jz INPUT_END
	
	call ReadUInt                                ; 调用ReadUInt,该函数将buf转换成整数,存放到ax中
	
	mov si, [number]
	shl si, 1                                    ; si = si * 2,一个数字占2个字节,因此乘以2
	mov [array+si], ax                           ; 将读取的数字存放到数组中
	shr si, 1
	inc si
	mov [number], si
	jmp INPUT
	
INPUT_END:
	push sp
	
	mov si, 0                                    ; 冒泡排序,i=si,j=di
	mov di, 0
L1:
	cmp si, [number]
	jge L1_END
	mov di, si                                   ; j = i + 1
	inc di
	L2:
		cmp di, [number]
		jge L2_END
		shl si, 1
		shl di, 1
		mov ax, [array+si]
		mov bx, [array+di]
		shr si, 1
		shr di, 1
		cmp ax, bx
		jg exchange
		inc di
		jmp L2
	exchange:
		shl si, 1
		shl di, 1
		mov [array+di], ax
		mov [array+si], bx
		shr si, 1
		shr di, 1
		inc di
		jmp L2
	L2_END:
		inc si
		jmp L1
	L1_END:
		
		mov bx, 0
	L3:
		cmp bx, [number]
		jge L3_END
		mov si, bx
		shl si, 1
		mov ax, [array+si]
		call print_int
		
		push bx
		push si
		
		mov dl, 13   ; 打印换行
		mov ah, 02h
		int 21h
		mov dl, 0ah
		mov ah, 02h
		int 21h
		
		pop si
		pop bx
		
		inc bx
		jmp L3
		
L3_END:
	pop sp
	mov ah, 4ch
	int 21h
	
ReadUInt proc
	pushf
	push bx
	push cx
	push dx
	push si
	push di
	
	mov cl, [buf+1]  ; 获取字符串长度
	mov ch, 0
	lea si, [buf+2]  ; 获取字符串地址
	mov ax, 0
	mov di, 0
ReadUInt_loop1:
	dec cx
	cmp cx, -1
	jz ReadUInt_loop1_end
	lea si, [buf+2]
	add si, di     ; 获取当前处理的字符地址
	inc di
	mov bl, [si]   ; 获取字符
	sub bl, 48     ; 字符减去'0'
	mov dl, 10
	mul dl         ; 乘以10
	mov bh, 0
	add ax, bx     ; 加上数字
	jmp ReadUInt_loop1
ReadUInt_loop1_end:
	
	pop di
	pop si
	pop dx
	pop cx
	pop bx
	popf
	ret
ReadUInt endp
 
print_int proc
	pushf            ; save eflags and register
	push bx
	push cx
	push dx
	
	cmp ax, 0
	jz print_zero
	jmp skip_print_zero
print_zero:
	mov dl, '0'
	mov ah, 02h
	int 21h
	jmp print_int_end2
skip_print_zero:
	
	mov cx, 0        ; digits of number
print_int_loop1:
	cmp ax, 0        ; number == 0 ? end
	jz print_int_end1
	mov dx, 0
	mov bx, 10
	div bx           ; 除以10
	push dx          ; 将余数保存到栈中
	inc cx           ; 位数加1
	jmp print_int_loop1
 
print_int_end1:
	cmp cx, 0        ;是否打印完成
	je print_int_end2
	pop dx
	add dl, '0'      ; 将数字加0,打印对应的ascii码
	mov ah, 02h
	int 21h
	dec cx
	jmp print_int_end1
	
print_int_end2:
	mov dl, 13   ; 打印换行
	mov ah, 02h
	int 21h
	
	pop dx
	pop cx
	pop bx
    popf
	ret
print_int endp
code ends
end main

 

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值