Как в 32-битной системе взять значения длинного текстового числа Если предпологаемое выходное значение не превышает 4-байта то сделать это очень просто Код (ASM): .data text db '1234567890' .code lea ecx,text xor eax,eax xor edx,edx Loc__1: mov dl,byte ptr [ecx] if dl sub dl,'0' imul eax,10 add eax,edx inc ecx jmp Loc__1 endif На выходе в регистре - eax будет полноценное значение - 1234567890 Но если текстовое число предпологает 8-байтное значение например к предыдущему примеру мы в текстовое число добавим в конце единицу то по сути должно получится 8-байтное значение - 02DFDC1C35h (hex-формат) но если мы пропустим это текстовое число через этот же алгоритм Код (ASM): .data text db '12345678901' .code lea ecx,text xor eax,eax xor edx,edx Loc__1: mov dl,byte ptr [ecx] if dl sub dl,'0' imul eax,10 add eax,edx inc ecx jmp Loc__1 endif То на выходе в регистре - eax будет значение только младшего (dword) 8-байтного значения - 0DFDC1C35h А как сделать так чтобы узнать значение старшего (dword) 8-байтного значения - 02h Кто в теме подскажите пожалуйста
Так у вас же есть команды для умножения. Просто сделайте умножение в столбик чисел с двумя 32-разрядными цифрами Код (ASM): .data text db '1234567890123456789', 0 .code push ebx push esi push edi lea ebx, [text] xor ecx, ecx xor esi, esi mov edi, 10 next: cmp byte [ebx], 0 ; Конец строки jz quit xchg eax, esi ; Умножаем старшую 32-разрядную цифру на основание ссч текстового числа mul edi xchg eax, ecx ; Умножаем младшую 32-разрядную цифру на основание ссч текстового числа mul edi add edx, ecx ; Учитываем перенос jc overflow ; Число больше 64 разрядов movzx ecx, byte [ebx] xor esi, esi sub ecx, '0' cmp ecx, edi ; Цифра числа верная (меньше основания ссч)? jae error add ecx, eax ; Складываем умноженное число с новой цифрой из строки adc esi, edx jnc next overflow: ; Ошибка в длине числа (превосходит 64 бита) push MB_OK or MB_ICONERROR push error_head push error_text push 0 call MessageBoxW xor ecx, ecx xor esi, esi jmp quit error: ; Ошибка в записи числа push MB_OK or MB_ICONERROR push error_head push error_text2 push 0 call MessageBoxW xor ecx, ecx xor esi, esi quit: mov eax, ecx mov edx, esi pop edi pop esi pop ebx retn error_head db 'Str2Int', 0 error_text db 'Value out of range!', 0 error_text2 db 'Invalid number!', 0
По итогу проанализировав полученные данные за которые огромное спасибо в том числе и данные полученные на дружественных сайтах я сформировал четыре пользовательские функции которые в принцыпи можно рассматривать просто как алгоритм действий Стоит обратить внимание на то что в функциях нет выявления ошибок и подразумевается что текстовое число имеет только десятичные символы с обязательным финализирующим нулём Каждая функция имеет только один параметр это адрес текстового числа Синтаксис функций не обычный но я думаю будет интуитивно понятным Если предполагаемое значение текстовых чисел 4-байта Код (ASM): func Fun1Dword esi,p[1] ;--------------------------------------------------------------------- mov esi,p1 xor eax,eax xor edx,edx Loc__1: mov dl,[esi] if dl sub dl,'0' imul eax,10 add eax,edx inc esi jmp Loc__1 endif ;--------------------------------------------------------------------- ; на выходе: ; eax - 4-байтное значение ;--------------------------------------------------------------------- end Если предполагаемое значение текстовых чисел 8-байт Код (ASM): func Fun2Dword esi edi ebx,p[1] ;--------------------------------------------------------------------- mov esi,p1 xor eax,eax ; младшие 4 байта (биты 0-3) xor edx,edx ; старшие 4 байта (биты 4-7) xor ecx,ecx Loc__1: mov cl,[esi] inc esi if cl sub cl,'0' add eax,eax ; *2 adc edx,edx mov edi,eax mov ebx,edx add eax,eax ; *4 adc edx,edx add eax,eax ; *8 adc edx,edx add eax,edi adc edx,ebx add eax,ecx jmp Loc__1 endif ;--------------------------------------------------------------------- ; на выходе: ; eax - младший dword 8-байтного значения ; edx - старший dword 8-байтного значения ;--------------------------------------------------------------------- end Если предполагаемое значение текстовых чисел 12-байт Код (ASM): func Fun3Dword esi edi ebx,p[1] ;--------------------------------------------------------------------- local tmp1,tmp2 ;--------------------------------------------------------------------- mov esi,p1 xor eax,eax ; младшие 4 байта (биты 0-3) xor edx,edx ; (биты 4-7) xor ebx,ebx ; старшие 4 байта (биты 8-11) xor ecx,ecx Loc__1: mov cl,[esi] if cl sub cl,'0' add eax,eax ; *2 adc edx,edx adc ebx,ebx mov edi,eax mov [tmp1],edx mov [tmp2],ebx add eax,eax ; *4 adc edx,edx adc ebx,ebx add eax,eax ; *8 adc edx,edx adc ebx,ebx add eax,edi adc edx,[tmp1] adc ebx,[tmp2] add eax,ecx adc edx,0 adc ebx,0 inc esi jmp Loc__1 endif ;--------------------------------------------------------------------- ; на выходе: ; eax - младший dword 12-байтного значения ; edx - следующий dword 12-байтного значения ; ebx - старший dword 12-байтного значения ;--------------------------------------------------------------------- end Если предполагаемое значение текстовых чисел 16-байт Код (ASM): func Fun4Dword esi edi ebx,p[1] ;--------------------------------------------------------------------- local tmp1,tmp2,tmp3,tmp4 ;--------------------------------------------------------------------- mov esi,p1 xor eax,eax ; младшие 4 байта (биты 0-3) xor edx,edx ; (биты 4-7) xor ebx,ebx ; (биты 8-11) xor edi,edi ; старшие 4 байта (биты 12-15) xor ecx,ecx Loc__1: mov cl,[esi] if cl sub cl,'0' add eax,eax ; *2 adc edx,edx adc ebx,ebx adc edi,edi mov [tmp1],eax mov [tmp2],edx mov [tmp3],ebx mov [tmp4],edi add eax,eax ; *4 adc edx,edx adc ebx,ebx adc edi,edi add eax,eax ; *8 adc edx,edx adc ebx,ebx adc edi,edi add eax,[tmp1] adc edx,[tmp2] adc ebx,[tmp3] adc edi,[tmp4] add eax,ecx adc edx,0 adc ebx,0 inc esi jmp Loc__1 endif ;--------------------------------------------------------------------- ; на выходе: ; eax - младший dword 16-байтного значения ; edx - следующий dword 16-байтного значения ; ebx - следующий dword 16-байтного значения ; edi - старший dword 16-байтного значения ;--------------------------------------------------------------------- end По сути то что я хотел я узнал Ещё раз всем спасибо за участие в теме Век живи век учись
128 бит показан в четвёртой функции а 256 и 512 бит тоже можно сделать просто для этого нужно больше задействовать переменных и освободить какой нибудь регистр для перекидывания данных но это чистой воды экзотика --- Сообщение объединено, 23 мар 2024 --- Прошу прощения в четвёртой функции из за рутины пропустил строчку кода после 37 строчки должно быть adc edi,0 Если это возможно прошу модераторов исправить --- Сообщение объединено, 23 мар 2024 --- Прошу прощения в четвёртой функции из за рутины пропустил строчку кода после 37 строчки должно быть adc edi,0 Если это возможно прошу модераторов исправить
В x64 регистров максимум еще один вагон (еще 8 регистров общего назначения), а маленькая тележка это уже SSE3+/AVX/AVX512 Я вот тоже в своем примере пропустил одну строчку. Вот исправленный пример Код (ASM): .data text db '1234567890123456789', 0 .code push ebx push esi push edi lea ebx, [text] xor ecx, ecx xor esi, esi mov edi, 10 next: cmp byte [ebx], 0 ; Конец строки jz quit xchg eax, esi ; Умножаем старшую 32-разрядную цифру на основание ссч текстового числа mul edi xchg eax, ecx ; Умножаем младшую 32-разрядную цифру на основание ссч текстового числа mul edi add edx, ecx ; Учитываем перенос jc overflow ; Число больше 64 разрядов movzx ecx, byte [ebx] xor esi, esi sub ecx, '0' cmp ecx, edi ; Цифра числа верная (меньше основания ссч)? jae error add ecx, eax ; Складываем умноженное число с новой цифрой из строки adc esi, edx inc ebx jnc next dec ebx overflow: ; Ошибка в длине числа (превосходит 64 бита) push MB_OK or MB_ICONERROR push error_head push error_text push 0 call MessageBoxW mov ecx, ebx xor esi, esi stc jmp quit error: ; Ошибка в записи числа push MB_OK or MB_ICONERROR push error_head push error_text2 push 0 call MessageBoxW mov ecx, ebx xor esi, esi stc quit: mov eax, ecx mov edx, esi pop edi pop esi pop ebx retn error_head db 'Str2Int', 0 error_text db 'Value out of range!', 0 error_text2 db 'Invalid number!', 0 Теперь при ошибке устанавливается флаг переноса и в eax возвращается указатель на символ с ошибкой.