Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Переведение целых в строку, DIV

602
06 мая 2008 года
KPI Student
265 / / 16.12.2006
При написании процедуры переведения целого в строку столкнулся со следующей проблемой - если пользоваться командой DIV, то делимое берется из dx:ax, делитель указывается, остаток записывается dx, частное в ax.
Отсюда и возникает ожидаемая проблема перевода dword в строку:
Если (dx:ax)*делитель > 65535, то частное не поместится а ах, возникнет integer overflow.
Код:
format PE GUI 4.0
entry start

include '%include%\win32a.inc'

section '.data' data readable writeable
  a dd 655360
  buf db ?,?,?,?,?,?,?,0      ; c-string

section '.code' code readable executable
  start:
        mov esi,[a]
        mov ecx,7
        mov edi,buf
        call IntToStrA
        invoke MessageBox,NULL,buf,buf,0
        invoke  ExitProcess,ecx

proc IntToStrA
; in: esi - integer, ecx - buf lenght, edi - buffer; out: ecx - symbols count
        push eax
        push ebx
        push edx
        mov ebx,ecx

        xor ecx,ecx     ; counter
        mov bx,10

        mov eax,esi
.next:  cmp eax,0
        jz .prn
        push eax
        and eax,0xFFFF0000
        shr eax,16
        mov dx,ax       ; high word of eax
        pop eax
        and eax,0x0000FFFF
        div bx             ; <dx:ax> / bx = ax(ch) + dx (os) ; exeption:integer overflow
        add dx,'0'
        push dx
        inc ecx
        cmp ebx, ecx
        je .prn                 ; max buffer
        jmp .next
.prn:
        jcxz .prn0
        xor edx,edx
.nx:    pop ax
        mov [edi+edx],al
        inc edx
        loop .nx
        mov ecx,edx
        jmp .exit
.prn0:
        mov [edi],byte '0'
        mov ecx,1
.exit:
        pop edx
        pop ebx
        pop eax
        ret
endp

section '.idata' import data readable writeable

  library kernel32,'KERNEL32.DLL',\
          user32,'USER32.DLL'

  include 'api\kernel32.inc'
  include '%include%\api\user32.inc'


Как решить данную проблему?
1.9K
06 мая 2008 года
disasm
232 / / 06.02.2006
Элементарно)) Почему бы не делить edx:eax на 32-разрядное число? Соответственно частное в eax, остаток в edx и ничего никуда не вылазит.
349
06 мая 2008 года
Phantom-84
656 / / 27.10.2005
Цитата: KPI Student
Как решить данную проблему?

Действительно, при использовании 32-раздядных регистров алгоритм полностью аналогичен. Если же требуется выполнить преобразование числа, находящегося в dx:ax, используя исключительно 16-разрядный код (или 64-разрядного числа из edx:eax, используя 32-разрядный код), то основной принцип остается тем же самым, только поначалу для выделения отдельной цифры будет выполняться двойное деление, пока в результате последовательного деления число не уменьшится до таких размеров, чтобы обрабатываться одной командой div. У меня к сожалению нет сейчас под рукой исходников соответствующей библиотеки, но я когда-то писал ее сам, поэтому точно помню, что там я использовал двойное деление.

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог