lib/lib_kernel_in_asm.asm

;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

你可能感兴趣的:(lib/lib_kernel_in_asm.asm)