From f111d6969ff27cd28c313ece5934521c22a03a38 Mon Sep 17 00:00:00 2001 From: "Sergey Semyonov (Serge)" Date: Wed, 23 May 2007 11:26:19 +0000 Subject: [PATCH] string manipulation routines for drivers and kernel enable global page support after paging git-svn-id: svn://kolibrios.org@519 a494cfbc-eb01-0410-851d-a64ba20cac60 --- kernel/trunk/core/exports.inc | 18 ++- kernel/trunk/core/ext_lib.inc | 27 +--- kernel/trunk/core/memory.inc | 254 ------------------------------- kernel/trunk/core/string.inc | 187 +++++++++++++++++++++++ kernel/trunk/core/taskman.inc | 22 +-- kernel/trunk/drivers/imports.inc | 20 +++ kernel/trunk/init.inc | 22 +-- kernel/trunk/kernel.asm | 31 ++-- kernel/trunk/kernel32.inc | 3 +- 9 files changed, 271 insertions(+), 313 deletions(-) create mode 100644 kernel/trunk/core/string.inc diff --git a/kernel/trunk/core/exports.inc b/kernel/trunk/core/exports.inc index 8a4e412e24..8eca40ad22 100644 --- a/kernel/trunk/core/exports.inc +++ b/kernel/trunk/core/exports.inc @@ -62,6 +62,13 @@ iglobal szSleep db 'Sleep',0 szGetTimerTicks db 'GetTimerTicks',0 + szStrncat db 'strncat',0 + szStrncpy db 'strncpy',0 + szstrncmp db 'strncmp',0 + szStrnlen db 'strnlen',0 + szStrchr db 'strchr',0 + szStrrchr db 'strrchr',0 + align 16 kernel_export: @@ -115,9 +122,18 @@ kernel_export: dd szSetMouseData , set_mouse_data dd szSleep , delay_ms dd szGetTimerTicks , get_timer_ticks + + dd szStrncat , strncat + dd szStrncpy , strncpy + dd szstrncmp , strncmp + dd szStrnlen , strnlen + dd szStrchr , strchr + dd szStrrchr , strrchr + + exp_lfb: dd szLFBAddress , 0 - dd 0 + dd 0 ;terminator, must be zero endg diff --git a/kernel/trunk/core/ext_lib.inc b/kernel/trunk/core/ext_lib.inc index 4b732502c0..277d5f13e1 100644 --- a/kernel/trunk/core/ext_lib.inc +++ b/kernel/trunk/core/ext_lib.inc @@ -56,9 +56,9 @@ proc load_k_library stdcall, file_name:dword img_base dd ? exports dd ? endl - + cli - + stdcall load_file, [file_name] test eax, eax jz .fail @@ -116,7 +116,7 @@ proc load_k_library stdcall, file_name:dword mov [strings], ecx lea eax, [edx+20] - + stdcall fix_coff_symbols, eax, [sym], [edx+CFH.nSymbols],\ [strings], dword 0 test eax, eax @@ -158,7 +158,7 @@ proc dll.Load, import_table:dword push esi mov edi,s_libname - + mov esi,sys_path @@: lodsb stosb @@ -228,7 +228,7 @@ proc dll.GetProcAddress, exp:dword,sz_name:dword mov edx,[exp] .next: test edx,edx jz .end - stdcall strcmp,[edx],[sz_name] + stdcall strncmp,[edx],[sz_name], dword -1 test eax,eax jz .ok add edx,8 @@ -306,21 +306,4 @@ proc mem.Free mptr ;////////////////////////////////////////////////////////// ret endp -proc strcmp, str1:dword,str2:dword - push esi edi - mov esi,[str1] - mov edi,[str2] - xor eax,eax - @@: lodsb - scasb - jne .fail - or al,al - jnz @b - jmp .ok - .fail: or eax,-1 - .ok: pop edi esi - ret -endp - - s_libname db 64 dup (0) diff --git a/kernel/trunk/core/memory.inc b/kernel/trunk/core/memory.inc index 5c4a59ce7b..0271ed58a3 100644 --- a/kernel/trunk/core/memory.inc +++ b/kernel/trunk/core/memory.inc @@ -1057,41 +1057,6 @@ proc set_mtrr stdcall, reg:dword,base:dword,size:dword,mem_type:dword endp -align 4 -proc strncmp stdcall, str1:dword, str2:dword, count:dword - - mov ecx,[count] - jecxz .end - - mov ebx,ecx - - mov edi,[str1] - mov esi,edi - xor eax,eax - repne scasb - neg ecx ; cx = count - strlen - add ecx,ebx ; strlen + count - strlen - -.okay: - mov edi,esi - mov esi,[str2] - repe cmpsb - mov al,[esi-1] - xor ecx,ecx - - cmp al,[edi-1] - ja .str2_big - je .end - -.str1_big: - sub ecx,2 - -.str2_big: - not ecx -.end: - mov eax,ecx - ret -endp align 4 proc stall stdcall, delay:dword @@ -1120,225 +1085,6 @@ proc stall stdcall, delay:dword ret endp -align 4 -k_strrchr: - push eax - xor eax,eax - or ecx,-1 - repne scasb - add ecx,1 - neg ecx - sub edi,1 - pop eax - std - repne scasb - cld - add edi,1 - - cmp [edi],al - jne @F - mov eax,edi - ret -@@: - xor eax,eax - ret - -align 4 -proc k_strncpy stdcall, dest:dword, src:dword, maxlen:dword - mov eax, [dest] - mov esi, [src] - mov ecx, [maxlen] - test eax, eax - jz .L9 - test esi, esi - jz .L9 - test ecx, ecx - jz .L9 - - sub esi, eax - jmp .L1 - -align 4 -.L2: - mov edx, [esi+eax] - mov [eax], dl - test dl, dl - jz .L7 - - mov [eax+1], dh - test dh, dh - jz .L6 - - shr edx, 16 - mov [eax+2],dl - test dl, dl - jz .L5 - - mov [eax+3], dh - test dh, dh - jz .L4 - add eax, 4 -.L1: - sub ecx, 4 - jae .L2 - - add ecx, 4 - jz .L9 - - mov dl, [eax+esi] - mov [eax], dl - test dl, dl - jz .L3 - - inc eax - dec ecx - jz .L9 - - mov dl, [eax+esi] - mov [eax], dl - test dl, dl - jz .L3 - - inc eax - dec ecx - jz .L9 - - mov dl, [eax+esi] - mov [eax], dl - test dl, dl - jz .L3 - - inc eax - jmp .L9 - -.L4: dec ecx - inc eax - -.L5: dec ecx - inc eax - -.L6: dec ecx - inc eax -.L7: - add ecx,3 - jz .L9 -.L8: - mov byte [ecx+eax], 0 -.L3: - dec ecx - jnz .L8 -.L9: - ret -endp - -if 0 - -magic equ 0xfefefeff - -k_strlen: - mov eax,[esp+4] - mov edx, 3 - - and edx, eax - jz .L1 - jp .L0 - - cmp dh, byte [eax] - je .L2 - - inc eax - cmp dh, byte [eax] - - je .L2 - - inc eax - xor edx, 2 - - jz .L1 -.L0: - cmp dh, [eax] - je .L2 - - inc eax - xor edx, edx - -.L1: - mov ecx, [eax] - add eax, 4 - - sub edx, ecx - add ecx, magic - - dec edx - jnc .L3 - - xor edx, ecx - and edx, not magic - jne .L3 - - mov ecx, [eax] - add eax, 4 - - sub edx, ecx - add ecx, magic - dec edx - jnc .L3 - - xor edx, ecx - and edx, not magic - jne .L3 - - mov ecx, [eax] - add eax, 4 - - sub edx, ecx - add ecx, magic - - dec edx - jnc .L3 - - xor edx, ecx - - and edx, not magic - jne .L3 - - mov ecx, [eax] - add eax, 4 - - sub edx, ecx - add ecx, magic - - dec edx - jnc .L3 - - xor edx, ecx - - and edx, not magic - je .L1 - -.L3: sub eax ,4 - sub ecx, magic - - cmp cl, 0 - jz .L2 - - inc eax - test ch, ch - jz .L2 - - shr ecx, 16 - inc eax - - cmp cl,0 - jz .L2 - - inc eax - -.L2: - sub eax, [esp+4] - ret - -end if if 0 push eax diff --git a/kernel/trunk/core/string.inc b/kernel/trunk/core/string.inc new file mode 100644 index 0000000000..9d22c8eb75 --- /dev/null +++ b/kernel/trunk/core/string.inc @@ -0,0 +1,187 @@ +$Revision: 431 $ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; Author: Kees J. Bot 1 Jan 1994 ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +; size_t strncat(char *s1, const char *s2, size_t n) +; Append string s2 to s1. + +; char *strchr(const char *s, int c) + + +; int strncmp(const char *s1, const char *s2, size_t n) +; Compare two strings. + +; char *strncpy(char *s1, const char *s2, size_t n) +; Copy string s2 to s1. + +; size_t strnlen(const char *s, size_t n) +; Return the length of a string. + +; proc strrchr stdcall, s:dword, c:dword +; Look for the last occurrence a character in a string. + +proc strncat stdcall, s1:dword, s2:dword, n:dword + push esi + push edi + mov edi, [s1] ; String s1 + mov edx, [n] ; Maximum length + + mov ecx, -1 + xor al, al ; Null byte + cld + repne scasb ; Look for the zero byte in s1 + dec edi ; Back one up (and clear 'Z' flag) + push edi ; Save end of s1 + mov edi, [s2] ; edi = string s2 + mov ecx, edx ; Maximum count + repne scasb ; Look for the end of s2 + jne @F + inc ecx ; Exclude null byte +@@: + sub edx, ecx ; Number of bytes in s2 + mov ecx, edx + mov esi, [s2] ; esi = string s2 + pop edi ; edi = end of string s1 + rep movsb ; Copy bytes + stosb ; Add a terminating null + mov eax, [s1] ; Return s1 + pop edi + pop esi + ret +endp + +align 4 +proc strncmp stdcall, s1:dword, s2:dword, n:dword + + push esi + push edi + mov ecx, [n] + test ecx, ecx ; Max length is zero? + je .done + + mov esi, [s1] ; esi = string s1 + mov edi, [s2] ; edi = string s2 + cld +.compare: + cmpsb ; Compare two bytes + jne .done + cmp byte [esi-1], 0 ; End of string? + je .done + dec ecx ; Length limit reached? + jne .compare +.done: + seta al ; al = (s1 > s2) + setb ah ; ah = (s1 < s2) + sub al, ah + movsx eax, al ; eax = (s1 > s2) - (s1 < s2), i.e. -1, 0, 1 + pop edi + pop esi + ret +endp + +align 4 +proc strncpy stdcall, s1:dword, s2:dword, n:dword + + push esi + push edi + + mov ecx, [n] ; Maximum length + mov edi, [s2] ; edi = string s2 + xor al, al ; Look for a zero byte + mov edx, ecx ; Save maximum count + cld + repne scasb ; Look for end of s2 + sub edx, ecx ; Number of bytes in s2 including null + xchg ecx, edx + mov esi, [s2] ; esi = string s2 + mov edi, [s1] ; edi = string s1 + rep movsb ; Copy bytes + + mov ecx, edx ; Number of bytes not copied + rep stosb ; strncpy always copies n bytes by null padding + mov eax, [s1] ; Return s1 + pop edi + pop esi + ret +endp + +align 4 +proc strnlen stdcall, s:dword, n:dword + + push edi + mov edi, [s] ; edi = string + xor al, al ; Look for a zero byte + mov edx, ecx ; Save maximum count + cmp cl, 1 ; 'Z' bit must be clear if ecx = 0 + cld + repne scasb ; Look for zero + jne @F + inc ecx ; Don't count zero byte +@@: + mov eax, edx + sub eax, ecx ; Compute bytes scanned + pop edi + ret +endp + +align 4 +proc strchr stdcall, s:dword, c:dword + push edi + cld + mov edi, [s] ; edi = string + mov edx, 16 ; Look at small chunks of the string +.next: + shl edx, 1 ; Chunks become bigger each time + mov ecx, edx + xor al, al ; Look for the zero at the end + repne scasb + pushf ; Remember the flags + sub ecx, edx + neg ecx ; Some or all of the chunk + sub edi, ecx ; Step back + mov eax, [c] ; The character to look for + repne scasb + je .found + popf ; Did we find the end of string earlier? + jne .next ; No, try again + xor eax, eax ; Return NULL + pop edi + ret +.found: + pop eax ; Get rid of those flags + lea eax, [edi-1] ; Address of byte found + pop edi + ret + +endp + + +proc strrchr stdcall, s:dword, c:dword + push edi + mov edi, [s] ; edi = string + mov ecx, -1 + xor al, al + cld + repne scasb ; Look for the end of the string + not ecx ; -1 - ecx = Length of the string + null + dec edi ; Put edi back on the zero byte + mov eax, [c] ; The character to look for + std ; Downwards search + repne scasb + cld ; Direction bit back to default + jne .fail + lea eax, [edi+1] ; Found it + pop edi + ret +.fail: + xor eax, eax ; Not there + pop edi + ret +endp + + diff --git a/kernel/trunk/core/taskman.inc b/kernel/trunk/core/taskman.inc index 613200c6ac..0da2ca7653 100644 --- a/kernel/trunk/core/taskman.inc +++ b/kernel/trunk/core/taskman.inc @@ -76,7 +76,6 @@ proc fs_execute pushad - mov [cmdline], ebx mov [flags], edx ; [ebp] pointer to filename @@ -84,12 +83,16 @@ proc fs_execute lea eax, [filename] mov dword [eax+1020],0 ;force terminate ;string - stdcall k_strncpy, eax, [ebp], 1023 + stdcall strncpy, eax, [ebp], 1023 + + mov [cmdline], ebx + test ebx, ebx + jz @F lea eax, [cmdline] mov dword [eax+252], 0 - stdcall k_strncpy, eax, [cmdline], 255 - + stdcall strncpy, eax, ebx, 255 +@@: lea eax, [filename] stdcall load_file, eax mov ecx, -ERROR_FILE_NOT_FOUND @@ -136,9 +139,8 @@ proc fs_execute _clear_ 256 ;clean extended information about process ; write application name - lea edi, [filename] - mov al, '/' - call k_strrchr ; now eax points to name without path + lea eax, [filename] + stdcall strrchr, eax, '/' ; now eax points to name without path lea esi, [eax+1] test eax, eax @@ -963,7 +965,7 @@ proc set_app_params stdcall,slot:dword, params:dword,\ .add_command_line: mov edx,[params] mov edx,[edx] ;app_cmdline - test edx,edx + test edx, [cmd_line] ;check both src & dst jz @F ;application don't need parameters mov eax, edx @@ -973,7 +975,7 @@ proc set_app_params stdcall,slot:dword, params:dword,\ cmp eax, [SLOT_BASE+APPDATA.mem_size+ebx*8] ja @f - stdcall k_strncpy, edx, [cmd_line], 256 + stdcall strncpy, edx, [cmd_line], 256 @@: mov edx,[params] mov edx, [edx+4] ;app_path @@ -984,7 +986,7 @@ proc set_app_params stdcall,slot:dword, params:dword,\ jc @f cmp eax, [SLOT_BASE+APPDATA.mem_size+ebx*8] ja @f - stdcall k_strncpy, edx, [app_path], 1024 + stdcall strncpy, edx, [app_path], 1024 @@: mov ebx,[slot] mov eax,ebx diff --git a/kernel/trunk/drivers/imports.inc b/kernel/trunk/drivers/imports.inc index c9642c402b..e579414ee2 100644 --- a/kernel/trunk/drivers/imports.inc +++ b/kernel/trunk/drivers/imports.inc @@ -145,6 +145,26 @@ end if if used GetTimerTicks extrn GetTimerTicks end if + +if used strncat + extrn strncat +end if +if used strncpy + extrn strncpy +end if +if used strncmp + extrn strncmp +end if +if used strnlen + extrn strnlen +end if +if used strchr + extrn strchr +end if +if used strrchr + extrn strrchr +end if + if used LFBAddress extrn LFBAddress end if diff --git a/kernel/trunk/init.inc b/kernel/trunk/init.inc index a91c6681f5..ef8e7f2150 100644 --- a/kernel/trunk/init.inc +++ b/kernel/trunk/init.inc @@ -71,12 +71,13 @@ proc init_mem or ebx, CR4_PSE mov eax, PG_LARGE+PG_SW - bt [cpu_caps-OS_BASE], CAPS_PGE - jnc @F +; bt [cpu_caps-OS_BASE], CAPS_PGE +; jnc @F - or eax, PG_GLOBAL - or ebx, CR4_PGE -@@: +; or eax, PG_GLOBAL +; or ebx, CR4_PGE +; +;@@: mov cr4, ebx dec [pg_data.kernel_tables-OS_BASE] @@ -122,15 +123,8 @@ proc init_mem mov edi, (sys_pgdir-OS_BASE) lea esi, [edi+(OS_BASE shr 20)] - lodsd - and eax, not PG_GLOBAL - stosd - lodsd - and eax, not PG_GLOBAL - stosd - lodsd - and eax, not PG_GLOBAL - stosd + movsd + movsd ret endp diff --git a/kernel/trunk/kernel.asm b/kernel/trunk/kernel.asm index 4ee58508d2..91cb222345 100644 --- a/kernel/trunk/kernel.asm +++ b/kernel/trunk/kernel.asm @@ -267,19 +267,28 @@ org OS_BASE+$ align 4 high_code: - mov ax,os_stack - mov bx,app_data - mov ss,ax - add esp, OS_BASE + mov ax,os_stack + mov bx,app_data + mov ss,ax + add esp, OS_BASE - mov ds,bx - mov es,bx - mov fs,bx - mov gs,bx + mov ds,bx + mov es,bx + mov fs,bx + mov gs,bx - mov dword [sys_pgdir], 0 - mov dword [sys_pgdir+4], 0 - mov dword [sys_pgdir+8], 0 + bt [cpu_caps], CAPS_PGE + jnc @F + + or dword [sys_pgdir+(OS_BASE shr 20)], PG_GLOBAL + + mov ebx, cr4 + or ebx, CR4_PGE + mov cr4, ebx +@@: + xor eax, eax + mov dword [sys_pgdir], eax + mov dword [sys_pgdir+4], eax mov eax, cr3 mov cr3, eax ; flush TLB diff --git a/kernel/trunk/kernel32.inc b/kernel/trunk/kernel32.inc index 8966dcaac1..6be981f574 100644 --- a/kernel/trunk/kernel32.inc +++ b/kernel/trunk/kernel32.inc @@ -171,6 +171,7 @@ include "core/malloc.inc" ; small kernel heap include "core/taskman.inc" include "core/dll.inc" include "core/exports.inc" +include "core/string.inc" ; GUI stuff include "gui/window.inc" @@ -255,4 +256,4 @@ include "core/conf_lib.inc" include "core/ext_lib.inc" ; list of external functions -include "lib_func.inc" \ No newline at end of file +include "lib_func.inc"