保护模式下的冒泡排序

  1 ;16位代码
  2 [bits 16]
  3 ;初始化实模式下的数据段,代码段,堆栈段
  4         mov eax, cs
  5         mov ss, eax
  6         mov sp, 0x7C00                    ;实模式下的栈在引导扇区的下边
  7 ;将保护模式下的线性地址转换为实模式下的段地址:偏移地址的形式
  8         xor edx, edx                    ;此处使用64位除法, 高32位清零
  9         mov eax, [cs:gdt_base + 0x7C00]    ;使用超越段前缀访问数据
 10         mov ebx,16                     ;线性地址 = 段地址 X 16 + 偏移地址
 11         div ebx
 12 ;设置指向描述符的数据段
 13         mov ebx, edx                    ;余数为偏移地址
 14         mov ds,     eax                    
 15 ;安装数据段描述符
 16     ;#0空描述符
 17         mov dword [ebx + 0x00], 0x0000_0000
 18         mov dword [ebx + 0x04], 0x0000_0000
 19     ;#1代码段
 20         mov dword [ebx + 0x08],    0x7C00_01FF
 21         mov dword [ebx + 0x0C], 0x0040_9800
 22     ;#2数据段
 23         mov dword [ebx + 0x10], 0x0000_FFFF
 24         mov dword [ebx + 0x14], 0x00CF_9200
 25     ;#3别名代码段
 26         mov dword [ebx + 0x18], 0x7C00_01FF
 27         mov dword [ebx + 0x1C], 0x0040_9200
 28     ;#4堆栈段
 29         mov dword [ebx + 0x20], 0x0000_6BFF
 30         mov dword [ebx + 0x24], 0x0040_9600
 31 ;加载GDT
 32         mov word [cs:gdt_size + 0x7C00], 0x27
 33         lgdt [cs:gdt_size + 0x7C00]
 34 ;打开A20
 35     in al, 0x92
 36     or al, 0000_0010B
 37     out 0x92, al
 38 ;关中断
 39     cli
 40 ;进入保护模式(16位)
 41     mov eax, cr0
 42     or    eax, 0000_0001B
 43     mov cr0, eax
 44 ;进入保护模式(32位)
 45     jmp dword 0x08:flush
 46 ;32位代码
 47 [bits 32]
 48     flush:
 49     ;加载别名代码段
 50     mov eax, 0x18
 51     mov ds, eax
 52     
 53     ;加载数据段
 54     mov eax, 0x10
 55     mov es, eax
 56     
 57     ;加载堆栈
 58     mov eax, 0x20
 59     mov ss, eax
 60     mov esp, 0x0000_7BFF
 61     
 62     ;在屏幕上启动信息字符
 63         mov ecx, gdt_size - welcome
 64         xor ebx, ebx
 65     wel:
 66         mov al, [ebx + welcome]
 67         mov ah, 0x0A
 68         mov [es:0x000B_8000 + ebx * 2], ax
 69         inc ebx
 70     loop wel
 71     ;冒泡排序
 72         mov ecx, welcome - string - 1
 73     external:
 74         xor ebx, ebx
 75         push ecx
 76     internal:
 77         mov ax, [ebx + string]
 78         cmp ah, al
 79         jg con
 80         xchg ah, al
 81         mov word [ebx + string], ax
 82     con:
 83         inc ebx
 84     loop internal
 85         pop ecx
 86     loop external
 87     ;显示排序的结果
 88     mov ecx, welcome - string
 89         xor ebx, ebx
 90     res:
 91         mov al, [ebx + string]
 92         mov ah, 0x0A
 93         mov [es:0x000B_8000 + 160 + ebx * 2], ax
 94         inc ebx
 95     loop res
 96     ;停机
 97          hlt 
 98 ;要进行排序的串
 99         string:     db '958458456541186545552135789642589103598416552556'
100         welcome:    db 'Welcome to Lixiaomao boot.'
101 ;GDT位置和界限
102         gdt_size:    dw    0                ;这个字用于存放GDT的界限
103         gdt_base:    dd    0x0000_7E00        ;打算将GDT放在引导扇区的后边
104 ;填充剩余扇区
105     times 510 - ($ - $$)    db  0
106                     db 0x55, 0xAA

 

posted @ 2015-02-15 15:26  李晓茂的杂货铺  阅读(255)  评论(0编辑  收藏  举报