diff --git a/programs/develop/str_double/trunk/str_double.asm b/programs/develop/str_double/trunk/str_double.asm index 0f63182046..4189e86ff4 100644 --- a/programs/develop/str_double/trunk/str_double.asm +++ b/programs/develop/str_double/trunk/str_double.asm @@ -10,14 +10,16 @@ ; 3) число в машинном виде (float) перевести в строковый вид (5 знаков после запятой) use32 - org 0x0 + org 0 db 'MENUET01' - dd 0x01,start,i_end,e_end,e_end,0,sys_path + dd 1,start,i_end,e_end,e_end,0,sys_path include '../../../proc32.inc' include '../../../macros.inc' +include '../../../KOSfuncs.inc' include '../../../develop/libraries/box_lib/load_lib.mac' include '../../../develop/libraries/box_lib/trunk/box_lib.mac' +include '../../../develop/info3ds/info_fun_float.inc' include 'lang.inc' @use_library @@ -27,12 +29,12 @@ start: load_libraries l_libs_start,l_libs_end ;проверка на сколько удачно загузилась наша библиотека mov ebp,lib_0 - cmp dword [ebp+ll_struc_size-4],0 + cmp dword[ebp+ll_struc_size-4],0 jz @f - mcall -1 ;exit not correct + mcall SF_TERMINATE_PROCESS @@: - mcall 40,0x27 - mcall 48, 3, sys_colors, 40 + mcall SF_SET_EVENTS_MASK,0xC0000027 + mcall SF_STYLE_SETTINGS,SSF_GET_COLORS, sys_colors, sizeof.system_colors edit_boxes_set_sys_color edit1,editboxes_end,sys_colors option_boxes_set_sys_color sys_colors,Option_boxes1 @@ -42,7 +44,7 @@ red: align 4 still: - mcall 10 ; функция 10 - ждать события + mcall SF_WAIT_EVENT cmp eax,1 ; перерисовать окно ? je red ; если да - на метку red @@ -55,313 +57,135 @@ still: jmp still ; если другое событие - в начало цикла -;--------------------------------------------------------------------- +align 4 key: ; нажата клавиша на клавиатуре - mcall 2 + mcall SF_GET_KEY ;cmp ah,13 - stdcall [edit_box_key], dword edit1 + stdcall [edit_box_key], edit1 jmp still ; вернуться к началу цикла -; Количество знаков числа после запятой (1-17) -NumberSymbolsAD DW 5 -; Константы (10 в степени N) -MConst DQ 1.0E1,1.0E2,1.0E3,1.0E4,1.0E5 - DQ 1.0E6,1.0E7,1.0E8,1.0E9,1.0E10 - DQ 1.0E11,1.0E12,1.0E13,1.0E14,1.0E15 - DQ 1.0E16,1.0E17,1.0E18,1.0E19,1.0E20 - DQ 1.0E21,1.0E22,1.0E23,1.0E24,1.0E25 - DQ 1.0E26,1.0E27,1.0E28,1.0E29,1.0E30 - DQ 1.0E31,1.0E32,1.0E33,1.0E34,1.0E35 - DQ 1.0E36,1.0E37,1.0E38,1.0E39,1.0E40 - DQ 1.0E41,1.0E42,1.0E43,1.0E44,1.0E45 - DQ 1.0E46,1.0E47,1.0E48,1.0E49,1.0E50 - DQ 1.0E51,1.0E52,1.0E53,1.0E54,1.0E55 - DQ 1.0E56,1.0E57,1.0E58,1.0E59,1.0E60 - DQ 1.0E61,1.0E62,1.0E63,1.0E64,1.0E65 - DQ 1.0E66,1.0E67,1.0E68,1.0E69,1.0E70 - DQ 1.0E71,1.0E72,1.0E73,1.0E74,1.0E75 - DQ 1.0E76,1.0E77,1.0E78,1.0E79,1.0E80 - DQ 1.0E81,1.0E82,1.0E83,1.0E84,1.0E85 - DQ 1.0E86,1.0E87,1.0E88,1.0E89,1.0E90 - DQ 1.0E91,1.0E92,1.0E93,1.0E94,1.0E95 - DQ 1.0E96,1.0E97,1.0E98,1.0E99,1.0E100 - DQ 1.0E101,1.0E102,1.0E103,1.0E104,1.0E105 - DQ 1.0E106,1.0E107,1.0E108,1.0E109,1.0E110 - DQ 1.0E111,1.0E112,1.0E113,1.0E114,1.0E115 - DQ 1.0E116,1.0E117,1.0E118,1.0E119,1.0E120 - DQ 1.0E121,1.0E122,1.0E123,1.0E124,1.0E125 - DQ 1.0E126,1.0E127,1.0E128 -; Число с плавающей запятой двойной точности -Data_Double DQ ? -; Число в BCD-формате -Data_BCD DT ? -; Вспомогательный флаг -Data_Flag DB ? -; Знак результата (если не 0 - отрицательное число) -Data_Sign DB ? -; Строка для хранения числа в коде ASCII -Data_String DB 32 DUP (?) +align 4 +button: + mcall SF_GET_BUTTON + cmp ah, 1 ; если НЕ нажата кнопка с номером 1, + jne @f + mcall SF_TERMINATE_PROCESS + @@: + cmp ah, 5 + jne @f + cmp dword[option_group1],opt3 + jne .opt_3_end + stdcall conv_str_to_int,[edit1.text] + mov dword[Data_Double],eax + finit + fld dword[Data_Double] + fstp qword[Data_Double] + + ; Data_Double - преобразуемое число + mov word[NumberSymbolsAD],8 ; количество знаков числа после запятой (1-17) + call DoubleFloat_to_String + call String_crop_0 + mov dword[Data_Double],eax ;восстанавливаем значение в формате float + jmp .opt_all_end + .opt_3_end: + + mov esi,string1 + mov edi,Data_String + cld + mov ecx,32 + rep movsb + + call String_to_DoubleFloat + cmp dword[option_group1],opt1 + jne .opt_all_end ;если выбран float, то преобразуем из ранее полученного double + finit + fld qword[Data_Double] ;читаем из double + fstp dword[Data_Double] ;а возвращаем во float + .opt_all_end: + jmp red + @@: + jmp still + +align 4 +mouse: + stdcall [edit_box_mouse], edit1 + stdcall [option_box_mouse], Option_boxes1 + jmp still + +;------------------------------------------------ +align 4 +draw_window: + mcall SF_STYLE_SETTINGS,SSF_GET_COLORS, sys_colors, sizeof.system_colors + + mcall SF_REDRAW,SSF_BEGIN_DRAW + mov edx, 0x14000000 + or edx, [sys_colors.work] + mcall SF_CREATE_WINDOW, (200 shl 16)+300, (200 shl 16)+175, ,,title + + mcall SF_DEFINE_BUTTON, ((300-53) shl 16)+38, (145 shl 16)+15, 5, [sys_colors.work_button] ; кнопка Ok + + mov ecx, 0x80000000 + or ecx, [sys_colors.work_text] + mcall SF_DRAW_TEXT, (15 shl 16) +30,, binstr, + mcall , (15 shl 16) +58,, decstr, + mcall , ((240-56*3) shl 16) +58,, Data_String, + mcall , (15 shl 16) +72,, hexstr, + mcall , (15 shl 16)+150,, numstr, + + mov ecx, 0x80000000 + or ecx, [sys_colors.work_button_text] + mcall , ((300-42) shl 16)+149, , Okstr,3 + + cmp dword[option_group1],opt1 + je @f ;если выбран float, то старшие 4 байта (из double) не печатаем + cmp dword[option_group1],opt3 + je @f ;если выбран float, то старшие 4 байта (из double) не печатаем + mov ecx, dword[Data_Double+4] + mcall SF_DRAW_NUMBER, (8 shl 16)+256,,(185 shl 16)+72,[sys_colors.work_text] ; 16-ная + + mov ecx, dword[Data_Double+4] + mcall ,(8 shl 16)+512,,(240 shl 16)+30, ; 2-ная + ror ecx, 8 + mcall ,,,((240-56) shl 16)+30, + ror ecx, 8 + mcall ,,,((240-56*2) shl 16)+30, + ror ecx, 8 + mcall ,,,((240-56*3) shl 16)+30, + ror ecx, 8 + @@: + + mov ecx,dword[Data_Double] + mcall SF_DRAW_NUMBER, (8 shl 16)+256,,(240 shl 16)+72,[sys_colors.work_text] ; 16-ная + + mov ecx,dword[Data_Double] + mcall , (8 shl 16)+512,,(240 shl 16)+44, ; 2-ная + ror ecx, 8 + mcall ,,,((240-56) shl 16)+44, + ror ecx, 8 + mcall ,,,((240-56*2) shl 16)+44, + ror ecx, 8 + mcall ,,,((240-56*3) shl 16)+44, + ror ecx, 8 + + mcall SF_DRAW_LINE, (15 shl 16)+300-15, (137 shl 16)+137, [sys_colors.work_graph] + stdcall [edit_box_draw], edit1 + stdcall [option_box_draw], Option_boxes1 + mcall SF_REDRAW,SSF_END_DRAW + +ret + string1 db 32 dup (0) string1_end: - -;******************************************************* -;* ПРЕОБРАЗОВАНИЕ ЧИСЛА С ПЛАВАЮЩЕЙ ЗАПЯТОЙ В СТРОКУ * -;* Число имеет формат с удвоенной точностью, результат * -;* выдается в десятичном коде, в "бытовом" формате с * -;* фиксированным количеством знаков после запятой. * -;* Входные параметры: * -;* Data_Double - преобразуемое число; * -;* NumberSymbolsAD - количество знаков после * -;* запятой (0-17). * -;* Выходные параметры: * -;* Data_String - строка-результат. * -;******************************************************* -DoubleFloat_to_String: - pushad - ; Результат записывать в строку Data_String - mov EDI, Data_String - - ; Сдвигаем число влево на NumberSymbolsAD - ; десятичных разрядов - fninit ;сброс сопроцессора - fld [Data_Double] ;загрузить число - xor ebx,ebx - mov BX,[NumberSymbolsAD] - cmp BX, 0 - je .NoShifts ;нет цифр после запятой - jl .Error ;ошибка - dec BX - shl BX, 3 ;умножаем на 8 - add EBX, MConst - fmul qword [EBX] ;умножить на константу -.NoShifts: - ; Извлечь число в коде BCD - fbstp [Data_BCD] -; Проверить результат на переполнение - mov AX,word [Data_BCD + 8] - cmp AX,0FFFFh ;"десятичное" переполнение? - je .Overflow -; Выделить знак числа и записать его в ASCII-коде - mov AL, byte [Data_BCD + 9] - and AL,AL - jz .NoSign - mov AL,'-' - stosb -.NoSign: -; Распаковать число в код ASCII - mov ebx,8 ;смещение последней пары цифр - mov ecx,9 ;счетчик пар цифр - ; Определить позицию десятичной точки в числе - mov DX,18 - sub DX,[NumberSymbolsAD] - js .Error ;ошибка, если отрицательная - jz .Error ;или нулевая позиция -.NextPair: - ; Загрузить очередную пару разрядов - mov AL, byte [ebx + Data_BCD] - mov AH,AL - ; Выделить, перевести в ASCII и - ; сохранить старшую тетраду - shr AL,4 - add AL,'0' - stosb - dec DX - jnz .N0 - mov AL,'.' - stosb -.N0: ; Выделить, перевести в ASCII и - ; сохранить младшую тетраду - mov AL,AH - and AL,0Fh - add AL,'0' - stosb - dec DX - jnz .N1 - mov AL,'.' - stosb -.N1: - dec BX - loop .NextPair - mov AL,0 - stosb - -; Убрать незначащие нули слева - mov EDI, Data_String - mov ESI, Data_String - ; Пропустить знак числа, если он есть - cmp byte [ESI],'-' - jne .N2 - inc ESI - inc EDI -.N2: ; Загрузить в счетчик цикла количество разрядов - ; числа плюс 1 (байт десятичной точки) - mov ecx,18+1+1 - ; Пропустить незначащие нули -.N3: - cmp byte [ESI],'0' - jne .N4 - cmp byte [ESI+1],'.' - je .N4 - inc ESI - loop .N3 - ; Ошибка - нет значащих цифр - jmp .Error -; Скопировать значащую часть числа в начало строки -.N4: rep movsb - jmp .End - -; Ошибка -.Error: - mov AL,'E' - stosb - mov AL,'R' - stosb - mov AL,'R' - stosb - xor AL,AL - stosb - jmp .End -; Переполнение разрядной сетки -.Overflow: - mov AL,'#' - stosb - xor AL,AL - stosb -; Конец процедуры -.End: - popad - ret - -;**************************************************** -;* ПРЕОБРАЗОВАТЬ СТРОКУ В ЧИСЛО С ПЛАВАЮЩЕЙ ЗАПЯТОЙ * -;* (число имеет обычный, "бытовой" формат) * -;* Входные параметры: * -;* Data_String - число в коде ASCII. * -;* Выходные параметры: * -;* Data_Double - число в двоичном коде. * -;**************************************************** -String_to_DoubleFloat: - pushad - cld - ; Очищаем Data_BCD - mov dword [Data_BCD],0 - mov dword [Data_BCD+4],0 - mov word [Data_BCD+8],0 - ; Очищаем байт знака - mov [Data_Sign],0 - ; Заносим в SI указатель на строку - mov ESI, Data_String - ; Пропускаем пробелы перед числом - mov ecx,64 ;защита от зацикливания -.ShiftIgnore: - lodsb - cmp AL,' ' - jne .ShiftIgnoreEnd - loop .ShiftIgnore - jmp .Error -.ShiftIgnoreEnd: - ; Проверяем знак числа - cmp AL,'-' - jne .Positive - mov [Data_Sign],80h - lodsb -.Positive: - mov [Data_Flag],0 ;признак наличия точки - mov DX,0 ;позиция точки - mov ecx,18 ;макс. число разрядов -.ASCIItoBCDConversion: - cmp AL,'.' ;точка? - jne .NotDot - cmp [Data_Flag],0 ;точка не встречалась? - jne .Error - mov [Data_Flag],1 - lodsb - cmp AL,0 ;конец строки? - jne .NotDot - jmp .ASCIItoBCDConversionEnd -.NotDot: - ; Увеличить на 1 значение позиции точки, - ; если она еще не встречалась - cmp [Data_Flag],0 - jnz .Figures - inc DX -.Figures: - ; Символы числа должны быть цифрами - cmp AL,'0' - jb .Error - cmp AL,'9' - ja .Error - ; Пишем очередную цифру в младшую тетраду BCD - and AL,0Fh - or byte [Data_BCD],AL - ; Проверка на конец строки - cmp byte [ESI],0 - je .ASCIItoBCDConversionEnd - ; Сдвигаем BCD на 4 разряда влево - ; (сдвигаем старшие 2 байта) - mov AX,word [Data_BCD+6] - shld word [Data_BCD+8],AX,4 - ; (сдвигаем средние 4 байта) - mov EAX, dword [Data_BCD] - shld dword [Data_BCD+4],EAX,4 - ; (сдвигаем младшие 4 байта) - shl dword [Data_BCD],4 - ; Загружаем следующий символ в AL - lodsb - loop .ASCIItoBCDConversion - ; Если 19-й символ не 0 и не точка, - ; то ошибка переполнения - cmp AL,'.' - jne .NotDot2 - inc ecx - lodsb -.NotDot2: - cmp AL,0 - jne .Error ;переполнение разрядной сетки - -; ПРЕОБРАЗОВАТЬ ЧИСЛО ИЗ КОДА BCD В ВЕЩЕСТВЕННОЕ ЧИСЛО -.ASCIItoBCDConversionEnd: - ; Вписать знак в старший байт - mov AL,[Data_Sign] - mov byte [Data_BCD+9],AL - ; Сбросить регистры сопроцессора - fninit - ; Загрузить в сопроцессор число в BCD-формате - fbld [Data_BCD] - ; Вычислить номер делителя - mov EBX,18+1 - sub BX,CX - sub BX,DX - cmp EBX,0 - je .NoDiv - dec EBX - shl EBX,3 ;умножаем на 8 - add EBX, MConst - fdiv qword [EBX] ;разделить на константу -.NoDiv:; Выгрузить число в двоичном формате - fstp [Data_Double] - jmp .End - -.Error:; При любой ошибке обнулить результат - fldz ;занести ноль с стек сопроцессора - fstp [Data_Double] -.End: - popad - ret - - - ;input: ; buf - указатель на строку, число должно быть в 10 или 16 ричном виде ;output: ; eax - число align 4 -proc conv_str_to_int, buf:dword +proc conv_str_to_int uses ebx ecx esi, buf:dword xor eax,eax - push ebx ecx esi xor ebx,ebx mov esi,[buf] ;определение отрицательных чисел @@ -423,124 +247,11 @@ proc conv_str_to_int, buf:dword sub ecx,eax mov eax,ecx @@: - pop esi ecx ebx ret endp - - -;--------------------------------------------------------------------- -align 4 -button: - mcall 17 ; 17 - получить идентификатор нажатой кнопки - cmp ah, 1 ; если НЕ нажата кнопка с номером 1, - jne @f - mcall -1 - @@: - cmp ah, 5 - jne @f - cmp dword[option_group1],opt3 - jne .opt_3_end - stdcall conv_str_to_int,dword[edit1.text] - mov dword[Data_Double],eax - finit - fld dword[Data_Double] - fstp qword[Data_Double] - - ; Data_Double - преобразуемое число - ; NumberSymbolsAD - количество знаков после запятой (0-17) - call DoubleFloat_to_String - mov dword[Data_Double],eax ;восстанавливаем значение в формате float - jmp .opt_all_end - .opt_3_end: - - mov esi,string1 - mov edi,Data_String - cld - mov ecx,32 - rep movsb - - call String_to_DoubleFloat - cmp dword[option_group1],opt1 - jne .opt_all_end ;если выбран float, то преобразуем из ранее полученного double - finit - fld qword[Data_Double] ;читаем из double - fstp dword[Data_Double] ;а возвращаем во float - .opt_all_end: - jmp red - @@: - jmp still - -mouse: - stdcall [edit_box_mouse], edit1 - stdcall [option_box_mouse], Option_boxes1 - jmp still - -;------------------------------------------------ -align 4 -draw_window: - mcall 48, 3, sys_colors, sizeof.system_colors - - mcall 12, 1 - mov edx, 0x14000000 - or edx, [sys_colors.work] - mcall 0, 200*65536+300, 200*65536+175, ,,title - - mcall 8, (300-53)*65536+38,145*65536+ 15, 5,[sys_colors.work_button] ; кнопка Ok - - mov ecx, 0x80000000 - or ecx, [sys_colors.work_text] - mcall 4, 15*65536 +30,, binstr, - mcall , 15*65536 +58,, decstr, - mcall , (240-56*3)*65536 +58,, Data_String, - mcall , 15*65536 +72,, hexstr, - mcall , 15*65536+150,, numstr, - - mov ecx, 0x80000000 - or ecx, [sys_colors.work_button_text] - mcall , (300-42)*65536+149, , Okstr,3 - - cmp dword[option_group1],opt1 - je @f ;если выбран float, то старшие 4 байта (из double) не печатаем - cmp dword[option_group1],opt3 - je @f ;если выбран float, то старшие 4 байта (из double) не печатаем - mov ecx, dword[Data_Double+4] - mcall 47, 8*65536+256,,185*65536+72,[sys_colors.work_text] ; 16-ная - - mov ecx, dword[Data_Double+4] - mcall ,8*65536+512,,240*65536+30, ; 2-ная - ror ecx, 8 - mcall ,,,(240-56)*65536+30, - ror ecx, 8 - mcall ,,,(240-56*2)*65536+30, - ror ecx, 8 - mcall ,,,(240-56*3)*65536+30, - ror ecx, 8 - @@: - - mov ecx,dword[Data_Double] - mcall 47, 8*65536+256,,240*65536+72,[sys_colors.work_text] ; 16-ная - - mov ecx,dword[Data_Double] - mcall , 8*65536+512,,240*65536+44, ; 2-ная - ror ecx, 8 - mcall ,,,(240-56)*65536+44, - ror ecx, 8 - mcall ,,,(240-56*2)*65536+44, - ror ecx, 8 - mcall ,,,(240-56*3)*65536+44, - ror ecx, 8 - - mcall 38, 15*65536+300-15, 137*65536+137, [sys_colors.work_graph] - stdcall [edit_box_draw], edit1 - stdcall [option_box_draw], Option_boxes1 - mcall 12, 2 ; функция 12: сообщить ОС об отрисовке окна - -ret - - ;------------------------------------------------- -title db 'string to double 07.09.11',0 +title db 'string to double 20.08.19',0 hexstr db 'hex:',0 decstr db 'dec:',0 binstr db 'bin:',0 @@ -549,12 +260,16 @@ if lang eq ru numstr db 'Число:',0 Okstr db 'Ввод',0 head_f_i: - head_f_l db 'Системная ошибка',0 + head_f_l db '"Системная ошибка',0 + err_msg_found_lib_0 db 'Не найдена библиотека ',39,'box_lib.obj',39,'" -tE',0 + err_msg_import_0 db 'Ошибка при импорте библиотеки ',39,'box_lib',39,'" -tW',0 else numstr db 'Number:',0 Okstr db 'Ok',0 head_f_i: - head_f_l db 'System error',0 + head_f_l db '"System error',0 + err_msg_found_lib_0 db 'Sorry I cannot found library ',39,'box_lib.obj',39,'" -tE',0 + err_msg_import_0 db 'Error on load import library ',39,'box_lib',39,'" -tW',0 end if mouse_dd dd 0 @@ -576,8 +291,7 @@ Option_boxes1 dd opt1, opt2, opt3, 0 system_dir_0 db '/sys/lib/' lib_name_0 db 'box_lib.obj',0 -err_msg_found_lib_0 db 'Не найдена библиотека ',39,'box_lib.obj',39,0 -err_msg_import_0 db 'Ошибка при импорте библиотеки ',39,'box_lib',39,0 + l_libs_start: lib_0 l_libs lib_name_0, sys_path, library_path, system_dir_0,\ @@ -606,7 +320,8 @@ dd 0,0 i_end: sys_colors system_colors - rb 0x400 ;stack +align 16 sys_path rb 4096 library_path rb 4096 + rb 0x400 ;stack e_end: ; метка конца программы