OSDev

для всех
Текущее время: 10 май 2024, 14:40

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 10 ] 
Автор Сообщение
СообщениеДобавлено: 26 окт 2010, 19:02 

Зарегистрирован: 22 окт 2010, 13:22
Сообщения: 92
Откуда: Ртищево
Всем доброго вечера!

Написал процедуру для перевода целого положительного числа в строку, но у меня программа крушится на операции деления (div). Что у меня не так? Вот весь код:

Код:

; ********************************************************
;                   П Р О Ц Е Д У Р А
; ********************************************************

; -------------------------------------------------------{
; Название:   UnsignedNumberToString()
; Описание:   Преобразование 32-битного числа в строку
; Вход:      EAX - 32-битное число
; Выход:   EDI - указатель на строку
;         ECX - количество символов в строке
; --------------------------------------------------------
UnsignedNumberToString:
      mov EDI,string1
      mov ECX,0
      mov EBX,10
   
   UnsignedNumberToString__Label_Div:
      div EBX
   
      add EDX,48
      mov [EDI],byte DL
      inc EDI
      inc ECX
   
      cmp EAX,0
      jz UnsignedNumberToString__Label_NoDiv
      jmp UnsignedNumberToString__Label_Div
   
   UnsignedNumberToString__Label_NoDiv:
      cmp ECX,1
      jz UnsignedNumberToString__Label_NoBuild
      jmp UnsignedNumberToString__Label_Build
   
   UnsignedNumberToString__Label_Build:
      mov ESI,string1
      mov EDI,string2
      mov EBX,0
      
      UnsignedNumberToString__Label_Build_Copy:
         mov EDX,ECX
         sub EDX,EBX
         sub EDX,1
         
         add ESI,EBX
         add EDI,EDX
         
         mov AL,byte [ESI]
         mov [EDI],byte AL
         
         inc EBX

      cmp ECX,EBX
      jz UnsignedNumberToString__Label_BuildComplete
      jmp UnsignedNumberToString__Label_Build_Copy
   
   UnsignedNumberToString__Label_BuildComplete:
      mov EDI,string2
      jmp UnsignedNumberToString__Label_End
   
   UnsignedNumberToString__Label_NoBuild:
      mov EDI,string1
   
   UnsignedNumberToString__Label_End:
ret
; -------------------------------------------------------}

; ********************************************************
;                     Д А Н Н Ы Е
; ********************************************************

UnsignedNumberToString__Data:
   string1 db 0,0,0,0,0,0,0,0,0,0,0
   string2 db 0,0,0,0,0,0,0,0,0,0,0

_________________
Изучаю процессор...


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 26 окт 2010, 19:05 

Зарегистрирован: 22 окт 2010, 13:22
Сообщения: 92
Откуда: Ртищево
Данная процедура у меня вызывается уже из основного кода. До вызова данной процедуры у меня правильно работают другие процедуры (например, вывод текста), а вот уже после этой процедуры у меня не работает процедура вывода текста. Устанавливая в процедуре в разных местах команду ret, я смог узнать что после выполнения деления div, у меня программа рушится.

_________________
Изучаю процессор...


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 26 окт 2010, 21:31 

Зарегистрирован: 28 окт 2007, 18:33
Сообщения: 1418
Если виновата именно команда деления, то, возможно, Вы забыли сохранить какой-то регистр, который она использует. Другая возможная причина для этой команды -- попытка деления на 0 (всегда вызывает прерывание, что нередко крайне неудобно).


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 26 окт 2010, 23:04 

Зарегистрирован: 22 окт 2010, 13:22
Сообщения: 92
Откуда: Ртищево
На ноль точно ничего не делится, так как я использую деление на 10. Регистры используются такие:

1. EAX. Это число, которое будем делить и после деления тут будет результат деления.
2. EDX. Тут будет остаток от деления после деления.
3. EBX. Это то число, на которое мы делим число из регистра EAX.

Используем 32-битный делитель. Всё должно быть правильно. Смотрел по статье http://www.codenet.ru/progr/asm/newbee/lesson8.php. не понимаю в чём проблема. Ведь не должно же быть это связано с тем, что я использую 32-битные операторы для делении в режиме реальных адресов (R-Mode)?

_________________
Изучаю процессор...


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 26 окт 2010, 23:09 

Зарегистрирован: 10 май 2007, 11:33
Сообщения: 1206
Перед каждым делением нужно обнулять edx.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 26 окт 2010, 23:17 

Зарегистрирован: 22 окт 2010, 13:22
Сообщения: 92
Откуда: Ртищево
phantom-84 писал(а):
Перед каждым делением нужно обнулять edx.

Большое спасибо! Это помогло. Теперь всё работает. Конечно моя процедура работает не так как я хотел (выводит только если число от 0 до 9), но всё же уже работает. Буду исправлять. Ещё раз спасибо!

_________________
Изучаю процессор...


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 26 окт 2010, 23:31 

Зарегистрирован: 10 май 2007, 11:33
Сообщения: 1206
Чтобы не мучаться с выстраиванием цифр в правильном порядке, можно остатки от деления / цифры сохранять в стеке. При извлечении из стека они будут выстраиваться в правильном порядке.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 26 окт 2010, 23:33 

Зарегистрирован: 22 окт 2010, 13:22
Сообщения: 92
Откуда: Ртищево
phantom-84 писал(а):
Чтобы не мучаться с выстраиванием цифр в правильном порядке, можно остатки от деления / цифры сохранять в стеке. При извлечении из стека они будут выстраиваться в правильном порядке.

А разве можно в стек засунуть 8-битное (байт) значение?

_________________
Изучаю процессор...


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 26 окт 2010, 23:46 

Зарегистрирован: 22 окт 2010, 13:22
Сообщения: 92
Откуда: Ртищево
Всё, процедуру исправил. Всё работает! Интересно оказалось следующее...был код:

Код:
UnsignedNumberToString__Label_Build_Copy:
   mov EDX,ECX
   sub EDX,EBX
   sub EDX,1
         
   add ESI,EBX
   add EDI,EDX
         
   mov AL,byte [ESI]
   mov [EDI],byte AL
               
   inc EBX


И он работал не так как я хотел. Пришлось переписать так:

Код:
UnsignedNumberToString__Label_Build_Copy:
   mov EDX,ECX
   sub EDX,EBX
   sub EDX,1
         
   mov EDI,string1
   add EDI,EBX
   mov AL,byte [EDI]
   mov EDI,string2
   add EDI,EDX
   mov [EDI],byte AL
         
   inc EBX


Я ради интереса решил использовать только EDI (без ESI) и оказалось что не зря. Не пойму, почему же нельзя использовать один для указания на одну область данных, а другой на другую и через другой регистр обменять значения? Я ведь никаких специфических команд не использую.

_________________
Изучаю процессор...


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 26 окт 2010, 23:49 

Зарегистрирован: 10 май 2007, 11:33
Сообщения: 1206
s3dworld писал(а):
А разве можно в стек засунуть 8-битное (байт) значение?

Код:
  ...
@@:
  xor edx,edx
  div ebx
  inc ecx
  push edx
  and eax,eax
  jnz @b
@@:
  pop eax
  add al,"0"
  stosb
  loop @b
  ...


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 10 ] 

Часовой пояс: UTC + 3 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 97


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
Создано на основе phpBB® Forum Software © phpBB Group
Русская поддержка phpBB