- ;By Marcus Xing
- ;lib/lib_kernel_in_asm.asm
- ;内核中用到的用汇编写的工具函数
- ;注意,有些函数使用了IO操作,根据当前特权级和EFLAG的相应限制使用
- ;---------------------------------------------------------------------global集合
- global Disp_Str
- global Disp_Color_Str
- global I_To_A
- global Out_Byte
- global In_Byte
- global Memory_Copy
- global Enable_IRQ
- global Disable_IRQ
- global Enable_Int
- global Disable_Int
- ;---------------------------------------------------------------------extern集合
- extern d_Disp_Pos
- extern Cursor_Loc
- ;-----------------------------------------------------------------------Disp_Str
- Disp_Str:
- ;C函数原型:
- ;void Disp_Str(const char *psz_Str)
- ;打印一个字符串
- push ebp
- mov ebp,esp
- push eax
- push ebx
- push edx
- push esi
- push edi
- mov edi,[d_Disp_Pos] ;edi为显示位置
- mov esi,[ebp + 8] ;esi指向要打印的串
- .1:
- cmp byte [esi],0 ;判断串是否结束
- je .3 ;结束就退出打印
- cmp byte [esi],0ah ;判断是否是回车
- jne .2 ;不是就打印
- ;修改edi值,跳转下一行的开始
- mov eax,edi
- xor edx,edx
- mov ebx,160
- div ebx
- inc eax
- mul ebx
- mov edi,eax
- inc esi
- jmp .1 ;处理串下一个字符
- .2:
- mov ah,0fh ;黑底白字
- mov al,[esi]
- mov [gs:edi],ax ;写入显存
- add edi,2
- inc esi
- jmp .1 ;处理下一个字符
- .3:
- mov [d_Disp_Pos],edi ;把位置写回变量
- call Cursor_Loc ;调用功能函数,光标跟随字符
- pop edi
- pop esi
- pop edx
- pop ebx
- pop eax
- pop ebp
- ret
- ;-----------------------------------------------------------------Disp_Color_Str
- Disp_Color_Str:
- ;C函数原型:
- ;void Disp_Str(const char *psz_Str,u8 color)
- ;打印一个带颜色的字符串
- push ebp
- mov ebp,esp
- push eax
- push ebx
- push edx
- push esi
- push edi
- mov edi,[d_Disp_Pos] ;edi为显示位置
- mov esi,[ebp + 8] ;esi指向要打印的串
- mov eax,[ebp + 12] ;eax为颜色值
- mov ah,al ;颜色值送ah
- .1:
- cmp byte [esi],0 ;判断串是否结束
- je .3 ;结束就退出打印
- cmp byte [esi],0ah ;判断是否是回车
- jne .2 ;不是就打印
- ;修改edi值,跳转下一行的开始
- mov eax,edi
- xor edx,edx
- mov ebx,160
- div ebx
- inc eax
- mul ebx
- mov edi,eax
- inc esi
- jmp .1 ;处理串下一个字符
- .2:
- mov al,[esi]
- mov [gs:edi],ax ;写入显存
- add edi,2
- inc esi
- jmp .1 ;处理下一个字符
- .3:
- mov [d_Disp_Pos],edi ;把位置写回变量
- call Cursor_Loc ;调用功能函数,光标跟随字符
- pop edi
- pop esi
- pop edx
- pop ebx
- pop eax
- pop ebp
- ret
- ;-------------------------------------------------------------------------I_to_A
- I_To_A:
- ;C函数原型:
- ;void I_To_A(const char *p_sz_buffer,int num);
- ;把num中的数字转化为一个ASCII数组存放到buffer中,
- ;最高位的0去掉,以0x开头以16进制格式存放
- push ebp
- mov ebp,esp
- push eax
- push ecx
- push esi
- mov esi,[ebp + 8] ;BUFFER指针赋给esi
- ;开头2字符'0x'填充到BUFFER
- mov byte [esi],'0'
- inc esi
- mov byte [esi],'x'
- inc esi
- mov eax,[ebp + 12] ;要转化的数赋给eax
- test eax,eax ;测试eax是否为0
- je .4 ;如果为0则直接跳转到.4
- mov ecx,28 ;移位计数器
- .1:
- mov eax,[ebp + 12] ;要转化的数赋给eax
- shr eax,cl ;右移cl位
- and al,0fh ;清掉al高4位
- test al,al ;测试al是否为0
- jne .2 ;如果不为0则就开始继续填充BUFFER
- sub cl,4 ;cl减4
- jmp .1 ;继续左移
- .2:
- and al,0fh ;清掉al高4位
- cmp al,9 ;与9比较
- jbe .3 ;<=9则添砖到.3,直接加30h
- add al,7h ;>9则转化为A-F
- .3:
- add al,30h ;转化为相应的ASCII码
- mov byte [esi],al ;存入BUFFER
- inc esi ;指向下一个BUFFER
- cmp cl,0 ;判断cl==0
- je .5 ;if(cl==0) then 添上结束符
- sub cl,4 ;else go on
- mov eax,[ebp + 12] ;要转化的数赋给eax
- shr eax,cl
- jmp .2 ;跳转到.2
- .4:
- mov byte [esi],'0' ;处理num=0的情况
- inc esi
- .5:
- mov byte [esi],0 ;BUFFER最后置'/0'作为结束符
- pop esi
- pop ecx
- pop eax
- pop ebp
- ret
- ;-----------------------------------------------------------------------Out_Byte
- Out_Byte:
- ;C函数原型:
- ;void Out_Byte(u16 port,u8 value)
- ;向一个16位的端口写一个8位的值
- push ebp
- mov ebp,esp
- push eax
- push edx
- mov edx,[ebp + 8] ;端口值送edx
- mov eax,[ebp + 12] ;值送eax
- out dx,al ;out
- ;延时
- nop
- nop
- pop edx
- pop eax
- pop ebp
- ret
- ;------------------------------------------------------------------------In_Byte
- ;C函数原型:
- ;u8 In_Byte(u16 port);
- ;从端口读一个值并返回
- In_Byte:
- push ebp
- mov ebp,esp
- push edx
- mov edx,[ebp + 8] ;edx<-port
- in al,dx
- ;延时
- nop
- nop
- pop edx
- pop ebp
- ret
- ;--------------------------------------------------------------------Memory_Copy
- Memory_Copy:
- ;C函数原型:
- ;void Memory_Copy(void *dest,void *src,int len);
- ;数据从src流向dest,单位为len个字节
- push ebp
- mov ebp,esp
- push eax
- push ecx
- push esi
- push edi
- mov esi,[ebp + 12] ;esi指向源地址
- mov edi,[ebp + 8] ;edi指向目的地址
- mov ecx,[ebp + 16] ;ecx为复制字节数
- .1:
- mov al,byte [esi]
- mov byte [edi],al
- inc esi
- inc edi
- loop .1
- pop edi
- pop esi
- pop ecx
- pop eax
- pop ebp
- ret
- ;---------------------------------------------------------------------Enable_IRQ
- Enable_IRQ:
- ;C函数原型:
- ;void Enable_IRQ(int irq_no);
- ;激活irq_no号外中断
- push ebp
- mov ebp,esp
- push eax
- push ecx
- pushf ;标志寄存器进栈
- cli ;关中断
- mov ecx,[ebp + 8] ;中断号送ecx
- cmp cl,7 ;中断号>7,则为从片
- ja .1
- ;主片顺序执行
- in al,21h ;得到原主片的值
- ;得到欲比较的相应值
- mov ah,1
- shl ah,cl
- not ah
- and al,ah
- out 21h,al ;写回去
- jmp .2 ;ret
- .1:
- ;从片开始
- sub cl,8 ;减8
- in al,0a1h ;得到原从片的值
- ;得到欲比较的相应值
- mov ah,1
- shl ah,cl
- not ah
- and al,ah
- out 0a1h,al ;写回去
- .2:
- popf ;恢复标志寄存器
- pop ecx
- pop eax
- pop ebp
- ret
- ;--------------------------------------------------------------------Disable_IRQ
- Disable_IRQ:
- ;C函数原型:
- ;void Enable_IRQ(int irq_no);
- ;屏蔽irq_no号外中断
- push ebp
- mov ebp,esp
- push eax
- push ecx
- pushf ;标志寄存器进栈
- cli ;关中断
- mov ecx,[ebp + 8] ;中断号送ecx
- cmp cl,7 ;中断号>7,则为从片
- ja .1
- ;主片顺序执行
- in al,21h ;得到原主片的值
- ;得到欲比较的相应值
- mov ah,1
- shl ah,cl
- or al,ah
- out 21h,al ;写回去
- jmp .2 ;ret
- .1:
- ;从片开始
- sub cl,8 ;减8
- in al,0a1h ;得到原从片的值
- ;得到欲比较的相应值
- mov ah,1
- shl ah,cl
- or al,ah
- out 0a1h,al ;写回去
- .2:
- popf ;恢复标志寄存器
- pop ecx
- pop eax
- pop ebp
- ret
- ;---------------------------------------------------------------------Enable_Int
- Enable_Int:
- ;C函数原型:
- ;void Enable_Int();
- ;简单的开中断
- sti
- ret
- ;--------------------------------------------------------------------Disable_Int
- Disable_Int:
- ;C函数原型:
- ;void Disable_Int();
- ;简单的关中断
- cli
- ret