80386汇编_冒泡排序

本文档展示了一段汇编代码,用于在32位保护模式下实现字符串的字符排序。首先,代码设置了堆栈段和保护模式,然后通过GDT(全局描述表)初始化各段描述符,并开启A20地址线。接着,代码通过冒泡排序对字符串进行排序,最后在屏幕上显示出排序前后的字符串。这是一个关于操作系统底层和汇编语言编程的基础实践。
摘要由CSDN通过智能技术生成

文章目录

要求

1、进入32保护模式

2、在32保护模式下,对字符串进行按照字符大小进行排序

效果

第一行:成功进入保护模式
第二行:原字符串顺序
第三行:排序后字符串顺序

代码

;-------------------------------------------------------------------------------
		;设置堆栈段和栈指针
		mov ax,0x7a00
		mov ss,ax
		mov sp,0x0200

;-------------------------------------------------------------------------------
		;gdt线性地址计算
		mov dx,[cs:pgdt+0x7c04]
		mov ax,[cs:pgdt+0x7c02]
		mov bx,0x10
		div bx								;ax存商,dx存余
		mov ds,ax							;段地址
		mov bx,dx							;偏移地址

;-------------------------------------------------------------------------------
		;#0 段描述符,空描述符,处理器要求
		mov dword [bx],0x00000000
		mov dword [bx+0x04],0x00000000
		
		add bx,0x08
		;#1 数据段描述符
		mov dword [bx],0x0000ffff			;基地址为0,段界限0xfffff
		mov dword [bx+0x04],0x00cf9200		;粒度4KB,整个4GB空间
		
		add bx,0x08
		;#2 代码段描述符
		mov dword [bx],0x7c0001ff    		;基地址为0x00007c00,512字节 
		mov dword [bx+0x04],0x00409800    	;粒度为1个字节 

		add bx,0x08
		;#3 代码段的别名描述符
		mov dword [bx],0x7c0001ff    		;基地址为0x00007c00,512字节
		mov dword [bx+0x04],0x00409200    	;粒度为1个字节,用于读写代码段

		add bx,0x08
		;#4 栈段描述符
		mov dword [bx],0x7c00fffe			;基地址为0x00007c00,段界限0xffffe
		mov dword [bx+0x04],0x00cf9600		;粒度4KB,向下扩展,4096字节
		
		;gdtr初始化
		mov word [cs:pgdt+0x7c00],39		;gdt界限
		lgdt [cs:pgdt+0x7c00]
		
;-------------------------------------------------------------------------------
		;准备开启32保护
		in al,0x92							;南桥芯片端口
		or al,0000_0010B
		out 0x92,al							;A20地址线开启
		
		cli									;关中断(尚未建立中断向量表)
		
		mov eax,cr0
		or eax,0x01
		mov cr0,eax							;PE位设置,32保护开启
		
		;进入保护模式
		jmp dword 0x0010:flush				;0x0010=00000000000_10_000B

		[bits 32]
;-------------------------------------------------------------------------------
	flush:
		;代码段别名段设置
		mov eax,00000000000_11_000B
		mov ds,eax
		
		;数据段设置
		mov eax,00000000000_01_000B
		mov es,eax
		
		;栈段设置
		mov eax,0000000000_100_000B
		mov ss,eax
		mov esp,0x0
		
		;字符打印
		mov dword [es:0x0b8000],0x072e0750 ;字符'P''.'及其显示属性
		mov dword [es:0x0b8004],0x072e074d ;字符'M''.'及其显示属性
		mov dword [es:0x0b8008],0x07200720 ;两个空白字符及其显示属性
		mov dword [es:0x0b800c],0x076b076f ;字符'o''k'及其显示属性

;-------------------------------------------------------------------------------
		;排序前字符显示
		mov ecx,pgdt-string					;字符串长度
		xor ebx,ebx							;遍历字符串
	@0:
		mov ah,0x07
		mov al,[ebx+string]
		mov [es:0xb80a0+2*ebx],ax			;写入显存
		inc ebx
		loop @0
		
;-------------------------------------------------------------------------------
		;冒泡排序
		mov ecx,pgdt-string-1				;外层循环
	@1:
		push ecx							;压入外层循环ecx
		xor bx,bx							;遍历字符串
	@2:										;内层循环
		mov ax,[bx+string]					;获取两个字符
		cmp ah,al
		jge @3								;若前一个字符(al)<后一个字符(ah)则跳转
		xchg ah,al							;交换ah,al
		mov [bx+string],ax					;填回交换后的ah,al
	@3:
		inc bx								;向前推进一位
		loop @2
		pop ecx								;返回外层循环
		loop @1

;-------------------------------------------------------------------------------
		;排序后字符显示
		mov ecx,pgdt-string					;字符串长度
		xor ebx,ebx							;遍历字符串
	@4:
		mov ah,0x07
		mov al,[ebx+string]
		mov [es:0xb8140+2*ebx],ax			;写入显存
		inc ebx
		loop @4
		
;-------------------------------------------------------------------------------		
		;停机指令
		hlt

;-------------------------------------------------------------------------------
    string      db 's0ke4or92xap3fv8giuzjcy5l1m7hd6bnqtw.'
;-------------------------------------------------------------------------------
    pgdt        dw 0
                dd 0x00007e00			   ;GDT的物理地址
;-------------------------------------------------------------------------------                             
times 510-($-$$)db 0
				db 0x55,0xaa
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值