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
This commit is contained in:
Sergey Semyonov (Serge) 2007-05-23 11:26:19 +00:00
parent eb55d78ee2
commit f111d6969f
9 changed files with 271 additions and 313 deletions

View File

@ -62,6 +62,13 @@ iglobal
szSleep db 'Sleep',0 szSleep db 'Sleep',0
szGetTimerTicks db 'GetTimerTicks',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 align 16
kernel_export: kernel_export:
@ -115,9 +122,18 @@ kernel_export:
dd szSetMouseData , set_mouse_data dd szSetMouseData , set_mouse_data
dd szSleep , delay_ms dd szSleep , delay_ms
dd szGetTimerTicks , get_timer_ticks 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: exp_lfb:
dd szLFBAddress , 0 dd szLFBAddress , 0
dd 0 dd 0 ;terminator, must be zero
endg endg

View File

@ -228,7 +228,7 @@ proc dll.GetProcAddress, exp:dword,sz_name:dword
mov edx,[exp] mov edx,[exp]
.next: test edx,edx .next: test edx,edx
jz .end jz .end
stdcall strcmp,[edx],[sz_name] stdcall strncmp,[edx],[sz_name], dword -1
test eax,eax test eax,eax
jz .ok jz .ok
add edx,8 add edx,8
@ -306,21 +306,4 @@ proc mem.Free mptr ;//////////////////////////////////////////////////////////
ret ret
endp 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) s_libname db 64 dup (0)

View File

@ -1057,41 +1057,6 @@ proc set_mtrr stdcall, reg:dword,base:dword,size:dword,mem_type:dword
endp 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 align 4
proc stall stdcall, delay:dword proc stall stdcall, delay:dword
@ -1120,225 +1085,6 @@ proc stall stdcall, delay:dword
ret ret
endp 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 if 0
push eax push eax

View File

@ -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

View File

@ -76,7 +76,6 @@ proc fs_execute
pushad pushad
mov [cmdline], ebx
mov [flags], edx mov [flags], edx
; [ebp] pointer to filename ; [ebp] pointer to filename
@ -84,12 +83,16 @@ proc fs_execute
lea eax, [filename] lea eax, [filename]
mov dword [eax+1020],0 ;force terminate mov dword [eax+1020],0 ;force terminate
;string ;string
stdcall k_strncpy, eax, [ebp], 1023 stdcall strncpy, eax, [ebp], 1023
mov [cmdline], ebx
test ebx, ebx
jz @F
lea eax, [cmdline] lea eax, [cmdline]
mov dword [eax+252], 0 mov dword [eax+252], 0
stdcall k_strncpy, eax, [cmdline], 255 stdcall strncpy, eax, ebx, 255
@@:
lea eax, [filename] lea eax, [filename]
stdcall load_file, eax stdcall load_file, eax
mov ecx, -ERROR_FILE_NOT_FOUND mov ecx, -ERROR_FILE_NOT_FOUND
@ -136,9 +139,8 @@ proc fs_execute
_clear_ 256 ;clean extended information about process _clear_ 256 ;clean extended information about process
; write application name ; write application name
lea edi, [filename] lea eax, [filename]
mov al, '/' stdcall strrchr, eax, '/' ; now eax points to name without path
call k_strrchr ; now eax points to name without path
lea esi, [eax+1] lea esi, [eax+1]
test eax, eax test eax, eax
@ -963,7 +965,7 @@ proc set_app_params stdcall,slot:dword, params:dword,\
.add_command_line: .add_command_line:
mov edx,[params] mov edx,[params]
mov edx,[edx] ;app_cmdline mov edx,[edx] ;app_cmdline
test edx,edx test edx, [cmd_line] ;check both src & dst
jz @F ;application don't need parameters jz @F ;application don't need parameters
mov eax, edx 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] cmp eax, [SLOT_BASE+APPDATA.mem_size+ebx*8]
ja @f ja @f
stdcall k_strncpy, edx, [cmd_line], 256 stdcall strncpy, edx, [cmd_line], 256
@@: @@:
mov edx,[params] mov edx,[params]
mov edx, [edx+4] ;app_path mov edx, [edx+4] ;app_path
@ -984,7 +986,7 @@ proc set_app_params stdcall,slot:dword, params:dword,\
jc @f jc @f
cmp eax, [SLOT_BASE+APPDATA.mem_size+ebx*8] cmp eax, [SLOT_BASE+APPDATA.mem_size+ebx*8]
ja @f ja @f
stdcall k_strncpy, edx, [app_path], 1024 stdcall strncpy, edx, [app_path], 1024
@@: @@:
mov ebx,[slot] mov ebx,[slot]
mov eax,ebx mov eax,ebx

View File

@ -145,6 +145,26 @@ end if
if used GetTimerTicks if used GetTimerTicks
extrn GetTimerTicks extrn GetTimerTicks
end if 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 if used LFBAddress
extrn LFBAddress extrn LFBAddress
end if end if

View File

@ -71,12 +71,13 @@ proc init_mem
or ebx, CR4_PSE or ebx, CR4_PSE
mov eax, PG_LARGE+PG_SW mov eax, PG_LARGE+PG_SW
bt [cpu_caps-OS_BASE], CAPS_PGE ; bt [cpu_caps-OS_BASE], CAPS_PGE
jnc @F ; jnc @F
or eax, PG_GLOBAL ; or eax, PG_GLOBAL
or ebx, CR4_PGE ; or ebx, CR4_PGE
@@: ;
;@@:
mov cr4, ebx mov cr4, ebx
dec [pg_data.kernel_tables-OS_BASE] dec [pg_data.kernel_tables-OS_BASE]
@ -122,15 +123,8 @@ proc init_mem
mov edi, (sys_pgdir-OS_BASE) mov edi, (sys_pgdir-OS_BASE)
lea esi, [edi+(OS_BASE shr 20)] lea esi, [edi+(OS_BASE shr 20)]
lodsd movsd
and eax, not PG_GLOBAL movsd
stosd
lodsd
and eax, not PG_GLOBAL
stosd
lodsd
and eax, not PG_GLOBAL
stosd
ret ret
endp endp

View File

@ -277,9 +277,18 @@ high_code:
mov fs,bx mov fs,bx
mov gs,bx mov gs,bx
mov dword [sys_pgdir], 0 bt [cpu_caps], CAPS_PGE
mov dword [sys_pgdir+4], 0 jnc @F
mov dword [sys_pgdir+8], 0
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 eax, cr3
mov cr3, eax ; flush TLB mov cr3, eax ; flush TLB

View File

@ -171,6 +171,7 @@ include "core/malloc.inc" ; small kernel heap
include "core/taskman.inc" include "core/taskman.inc"
include "core/dll.inc" include "core/dll.inc"
include "core/exports.inc" include "core/exports.inc"
include "core/string.inc"
; GUI stuff ; GUI stuff
include "gui/window.inc" include "gui/window.inc"