Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.146.221.204] |
|
Сообщ.
#1
,
|
|
|
Преобразование числа в строку и наоборот Два следующих алгоритма пригодятся всем кто не хочет использовать стандартные функции из библиотеки С, и тем кто пишет ОС либо пишет драйвер на ассемблере. функция dword_to_STR преобразовывает число в строку, число в строке может быть в любой системе счисления 2-16, если число больше чем 7FFFFFFF то число считается отрицательным dword_to_STR: ;на входе EAX число 32 бит ; ESI указатель на строку ; EBX разрядность результата (не больше 16) pushad cmp ebx, 16 ja .end cmp eax, 7FFFFFFFh jna .sign_plus mov byte [esi], '-' inc esi not eax inc eax .sign_plus: xor ecx, ecx jmp .repeat .mesto db 32 dup (0) .repeat: xor edx, edx div ebx mov edi, eax mov al, dl cmp al, 10 sbb al, 69h das mov byte [.mesto+ecx], al mov eax, edi inc ecx cmp eax, 0 jz .endrep jmp .repeat .endrep: mov edi, .mesto add edi, ecx .copyrep: dec edi mov dl, byte [edi] mov byte [esi], dl inc esi loop .copyrep .end: popad ret функция STR_to_DWORD преобразовывает число в строку, число в строке должно быть положительным, если происходит какая-либо ошибка, то результат 0 STR_to_DWORD: ; IN ESI = указатель на ZS строку ; EAX = разрядность ; OUT EAX = результат push esi push ebx push edi push edx push ecx cmp eax, 16 ja .error cmp eax, 2 jb .error mov ecx, eax mov edi, esi call GetZSLength mov edi, eax add edi, esi ; edi point to end ZS xor eax, eax xor edx, edx inc edx .rep: dec edi xor ebx, ebx mov bl, [edi] cmp bl, 30h jb .error cmp bl, 39h jna .digit cmp bl, 41h jb .error @@: cmp bl, 46h jna .sim_upcase cmp bl, 61h jb .error @@: cmp bl, 66h jna .sim_lowcase ja .error .digit: sub bl, 30h jmp @f .sim_upcase: sub bl, 37h jmp @f .sim_lowcase: sub bl, 57h @@: cmp bl, cl ja .error imul ebx, edx add eax, ebx imul edx, ecx cmp edi, esi jnz .rep .endrep: jmp @f .error: xor eax, eax @@: pop ecx pop edx pop edi pop ebx pop esi ret функция STR_to_DWORD_EX использует предыдущую функцию, но может преобразовывать и отрицательнгые числа, поддерживает только 2, 8, 10, 16 системы счисления, разрядность указывать не надо, она поределяет её сама по символу в конце числа (b-2, o-8, h-16, иначе -10) STR_to_DWORD_EX: ; IN ESI = pointer to ZS ; OUT EAX = result push esi push ebx push edi xor ebx, ebx cmp byte [esi], '-' jnz .sign_plus mov ebx, 1 inc esi .sign_plus: mov edi, esi call GetZSLength mov edi, eax add edi, esi dec edi cmp byte [edi], "b" jnz .oct mov eax, 2 xchg byte [edi], bh jmp .convert .oct: cmp byte [edi], "o" jnz .hex mov eax, 8 xchg byte [edi], bh jmp .convert .hex: cmp byte [edi], "h" jnz .decim mov eax, 16 xchg byte [edi], bh jmp .convert .decim: mov eax, 10 mov bh, byte [edi] .convert: call STR_to_DWORD xchg byte [edi], bh xor bh, bh cmp ebx, 1 jnz .end xor ebx, ebx sub ebx, eax mov eax, ebx .end: pop edi pop ebx pop esi ret Данными процедурками используется функция определения длины строки. GetZSLength: ; get zero-string length ;IN ; EDI ZS offset ;OUT ; EAX ZS length push ecx push esi cld xor al, al mov ecx, 0FFFFFFFFh mov esi, edi repne scasb sub edi, esi mov eax, edi dec eax pop esi pop ecx ret |
Сообщ.
#2
,
|
|
|
Перевод беззнакового 32-битного числа в строку:
dword_to_STR: ; eax - число ; edi - указатель на выходную строку push edx xor edx, edx div [_10] test eax, eax je stop_recursion call dword_to_STR stop_recursion: mov eax, edx add al, '0' stosb pop edx ret _10 dd 10 |