- Move source code from `trunk` into root directory for each program. - Update build files and ASM include paths. Add SPDX license header where appropriate. - Note: Line endings standardised from `CRLF` > `LF`, so best to view diffs with whitespace changes hidden. (Work towards #75, point 3) Reviewed-on: KolibriOS/kolibrios#417 Reviewed-by: Mikhail Frolov <mixa.frolov2003@gmail.com> Reviewed-by: Burer <burer@noreply.localhost> Co-authored-by: Andrew <dent.ace@gmail.com> Co-committed-by: Andrew <dent.ace@gmail.com>
178 lines
3.7 KiB
FASM
178 lines
3.7 KiB
FASM
;
|
|
; Файл для работы со строковыми функциями
|
|
;
|
|
|
|
; str_len (str1)
|
|
; Длина строки (возвращается в eax)
|
|
|
|
; str_cat (str1, str2)
|
|
; Добавление к строке st1 строки str2
|
|
|
|
; str_n_cat (str1, str2, n_len)
|
|
; Добавление к строке st1 строки str2. Если строка str2 длиннее чем n_len, то добавляются первые n_len символов.
|
|
|
|
; conv_str_to_int (buf)
|
|
; Преобразование строки buf в число (возвращается в eax)
|
|
|
|
; convert_int_to_str (len)
|
|
; Преобразование числа (eax) в строку (edi). len - длинна строки edi, которую можно использовать для преобразования.
|
|
|
|
|
|
;output:
|
|
; eax = strlen
|
|
align 4
|
|
proc str_len, str1:dword
|
|
mov eax,[str1]
|
|
@@:
|
|
cmp byte[eax],0
|
|
je @f
|
|
inc eax
|
|
jmp @b
|
|
@@:
|
|
sub eax,[str1]
|
|
ret
|
|
endp
|
|
|
|
align 4
|
|
proc str_cat uses eax ecx edi esi, str1:dword, str2:dword
|
|
mov esi,[str2]
|
|
stdcall str_len,esi
|
|
mov ecx,eax
|
|
inc ecx
|
|
mov edi,[str1]
|
|
stdcall str_len,edi
|
|
add edi,eax
|
|
cld
|
|
repne movsb
|
|
ret
|
|
endp
|
|
|
|
align 4
|
|
proc str_n_cat uses eax ecx edi esi, str1:dword, str2:dword, n_len:dword
|
|
mov esi,[str2]
|
|
mov ecx,[n_len]
|
|
mov edi,[str1]
|
|
stdcall str_len,edi
|
|
add edi,eax
|
|
cld
|
|
repne movsb
|
|
mov byte[edi],0
|
|
ret
|
|
endp
|
|
|
|
;input:
|
|
; buf - указатель на строку, число должно быть в 10 или 16 ричном виде
|
|
;output:
|
|
; eax - число
|
|
align 4
|
|
proc conv_str_to_int uses ebx ecx esi, buf:dword
|
|
xor eax,eax
|
|
xor ebx,ebx
|
|
mov esi,[buf]
|
|
;определение отрицательных чисел
|
|
xor ecx,ecx
|
|
inc ecx
|
|
cmp byte[esi],'-'
|
|
jne @f
|
|
dec ecx
|
|
inc esi
|
|
@@:
|
|
|
|
cmp word[esi],'0x'
|
|
je .load_digit_16
|
|
|
|
.load_digit_10: ;считывание 10-тичных цифр
|
|
mov bl,byte[esi]
|
|
cmp bl,'0'
|
|
jl @f
|
|
cmp bl,'9'
|
|
jg @f
|
|
sub bl,'0'
|
|
imul eax,10
|
|
add eax,ebx
|
|
inc esi
|
|
jmp .load_digit_10
|
|
jmp @f
|
|
|
|
.load_digit_16: ;считывание 16-ричных цифр
|
|
add esi,2
|
|
.cycle_16:
|
|
mov bl,byte[esi]
|
|
cmp bl,'0'
|
|
jl @f
|
|
cmp bl,'f'
|
|
jg @f
|
|
cmp bl,'9'
|
|
jle .us1
|
|
cmp bl,'A'
|
|
jl @f ;отсеиваем символы >'9' и <'A'
|
|
.us1: ;составное условие
|
|
cmp bl,'F'
|
|
jle .us2
|
|
cmp bl,'a'
|
|
jl @f ;отсеиваем символы >'F' и <'a'
|
|
sub bl,32 ;переводим символы в верхний регистр, для упрощения их последущей обработки
|
|
.us2: ;составное условие
|
|
sub bl,'0'
|
|
cmp bl,9
|
|
jle .cor1
|
|
sub bl,7 ;convert 'A' to '10'
|
|
.cor1:
|
|
shl eax,4
|
|
add eax,ebx
|
|
inc esi
|
|
jmp .cycle_16
|
|
@@:
|
|
or ecx,ecx ;если число отрицательное
|
|
jnz @f
|
|
neg eax
|
|
inc eax
|
|
@@:
|
|
ret
|
|
endp
|
|
|
|
;input:
|
|
; eax - число
|
|
; edi - буфер для строки
|
|
; len - длинна буфера
|
|
;output:
|
|
align 4
|
|
proc convert_int_to_str, len:dword
|
|
pushad
|
|
mov esi,[len]
|
|
add esi,edi
|
|
dec esi
|
|
bt eax,31
|
|
jae @f
|
|
;если число отрицательное
|
|
neg eax
|
|
;inc eax ;???
|
|
mov byte[edi],'-'
|
|
inc edi
|
|
@@:
|
|
call .str
|
|
popad
|
|
ret
|
|
endp
|
|
|
|
align 4
|
|
.str:
|
|
mov ecx,0x0a ;задается система счисления изменяются регистры ebx,eax,ecx,edx входные параметры eax - число
|
|
;преревод числа в ASCII строку взодные данные ecx=система счисленя edi адрес куда записывать, будем строку, причем конец переменной
|
|
cmp eax,ecx ;сравнить если в eax меньше чем в ecx то перейти на @@-1 т.е. на pop eax
|
|
jb @f
|
|
xor edx,edx ;очистить edx
|
|
div ecx ;разделить - остаток в edx
|
|
push edx ;положить в стек
|
|
;dec edi ;смещение необходимое для записи с конца строки
|
|
call .str ;перейти на саму себя т.е. вызвать саму себя и так до того момента пока в eax не станет меньше чем в ecx
|
|
pop eax
|
|
@@: ;cmp al,10 ;проверить не меньше ли значение в al чем 10 (для системы счисленя 10 данная команда - лишная))
|
|
cmp edi,esi
|
|
jge @f
|
|
or al,0x30 ;данная команда короче чем две выше
|
|
stosb ;записать элемент из регистра al в ячеку памяти es:edi
|
|
mov byte[edi],0 ;в конец строки ставим 0, что-бы не вылазил мусор
|
|
@@:
|
|
ret ;пока в стеке храниться кол-во вызовов то столько раз мы и будем вызываться
|