Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Asm: Общие вопросы > Проблема с функцией на FASM'е


Автор: Farmazon 27.10.2006, 18:44
Вот Эта функция для переаода числа в строку, которую я сваял, при вызове, срабатывает, а потом почему-то прога вылетает... Чё тока ниделал...  Не знаю почему лаги такие.... 

Код

proc toStr Addr, Val
local  TmpStr db 5 dup(0)
  mov eax, [Val]
  mov bx, 10
  mov ecx, 0
  ciclptsb1:
    mov dx, 0
    div bx
    add dl, 48
    mov [TmpStr + ecx], dl
    inc ecx
    or eax, eax
  jnz ciclptsb1
  mov eax, ecx

  mov edx, [Addr]
  ciclptsb2:
    dec ecx
    mov bl, byte [TmpStr + ecx]
    mov byte [edx], bl
    inc edx
    or ecx, ecx
  jnz ciclptsb2
  ret
endp
 

хотя если её переделать в макрокоманду - то всё пашет.... 

Код

TmpStr db 5 dup(0)
macro toStr Addr, Val
{
  mov eax, Val
  mov bx, 10
  mov ecx, 0
  ciclptsb1:
    mov dx, 0
    div bx
    add dl, 48
    mov [TmpStr + ecx], dl
    inc ecx
    or eax, eax
  jnz ciclptsb1
  mov eax, ecx

  mov edx, Addr
  ciclptsb2:
    dec ecx
    mov bl, byte [TmpStr + ecx]
    mov byte [edx], bl
    inc edx
    or ecx, ecx
  jnz ciclptsb2
}


Странно не правда ли? Я в принципе магу и 2 вариант до ума довести и заюзать... Но мне чиста интересна - ПАЧЕМУ НЕ РАБОТЕТ?!

Автор: Farmazon 27.10.2006, 20:30
А уже разобрался так...

Пути мокрософты не исповедимы... Я вызывал ету функцию в событии прорисовки окна = глюк. Запихал в другое место = всё норм!
 smile 

Автор: dumb 28.10.2006, 00:07
все регистры, кроме eax, edx, ecx сохранять надо и после использования восстанавливать. в данном случае, судя по описанию, проблема как-раз в несохранении ebx.

Автор: Farmazon 28.10.2006, 05:23
Не из-за этого... я добавлял "push ebx / pop ebx"... только толку шиш... Если функция используется в событии прорисовки окна - всё равно прога вылетает... А если в другом месте - всё норм.

Автор: sgi1981 28.10.2006, 10:13
Сохранять все регистры в начале каждой функции командой 
pushad
восстанавливать все регистры перед ret командой
popad

!!!


Автор: dumb 28.10.2006, 10:20
если это рисовалка, то в eax вроде как надо что-то осмысленное записать. типо 0.  smile 

Автор: Farmazon 28.10.2006, 11:00
Быть может и из-за eax... Хотя врядли когда етот же код напрямую сттавил (Макрокомандой) всё работало...

Автор: dumb 28.10.2006, 11:38
пригляделся. есть сурьезные основания считать, что причиной является маленький размер TmpStr: в варианте макроса он у тебя сидит в сегменте данных(с выравниваниями - т.е. либо вообще не задевает никого при переполнении, либо задевает, но то, что проявится потом), а в варианте процедуры - в стеке, который и рушится от переполнения TmpStr.
надо закладываться на максимальное кол-во цифр в числе. 11 - минимум, учитывая 0 в конце строки.

Автор: Farmazon 28.10.2006, 16:49
Нет..... У меня и на 2-значном числе вылетает.... Мне в моём случае и 5 хватит. Максимальное значение числа - 60000... 

А 0 в конце TempStr мне зачем? У мня в неё записываются (остатки от деления на 10) + 48, потом символы в обратном порядке записываются по нужному адресу... Еслиб мне нужна была строка PChar, то просто перед ret поставил  бы "mov byte [edx], 0"... Мне просто не PChar нужна... Мне нужно просто перевести число в текстовое представление, и узнать, какой оно длины в текстовом виде.

Да я говорю что видимых ошибок нет - я всё перепробовал! Когда я использую эту функцию не в событии прорисовки окна, то прога не вылетает! Вот сейчас засунул ея в таймер - нет проблем...

ЗЫ: Ай, вобщем фиг сним, проблема решена... Задерживаться на этой фигне и время терять не буду... Счас работает - и ладно... Спасибо конечно что пытались помочь... Тему можно закрыть.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)