2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




Начать новую тему Ответить на тему На страницу Пред.  1, 2
 
 Re: Ввод чисел на ассемблере
Сообщение29.11.2011, 04:04 


24/05/09

2054
Внесу и я свою посильную лепту, когда-то тож кодил на ассемблере. Функция переводит число из строки символов (коей и являются для процессора десятичные числа - он их совсем не понимает, учить приходится) в шестнадцатиричное в регистре, где с ним можно делать обычные арифметические операции. А вообще - как вы собираетесь писать довольно сложную прогу на ассемблере, если простой функции самостоятельно написать не можете?


Код:
;Процедура переводит число из dec (DI) в hex (AX)
;до первого символа, отличного от цифры (30h - 39h)
;
;возврат в AX,  DI на след. числе
;AX = 0  при переполнении или если 1й символ - не цифра


dec_hex:

        push    bx
        push    cx
        push    dx
        push    si

        xor     cx,cx
        mov     si,di

DH_1:
        lodsb
        cmp     al,'0'
        jl      DH_2
        cmp     al,'9'
        jg      DH_2
   
        inc     cl             ;счетчик цифр
        jmp     DH_1

DH_2:
        xor     ax,ax
        xor     bx,bx
   
        or      cl,cl
        je      DH_4            ;выход - 1й символ не цифра

DH_3:
        mov     dx,10
        mul      dx
        jno      DH_5

        xor     ax,ax      ;выход по переполнению
        jmp       DH_4

DH_5:
        mov     dl, [di+bx]
        sub     dl,'0'
        add     ax,dx
        inc     bx
        loop    DH_3

DH_4:
        mov     di,si
   
        pop     si
        pop     dx
        pop     cx
        pop     bx
        ret


 Профиль  
                  
 
 Re: Ввод чисел на ассемблере
Сообщение29.11.2011, 07:16 
Аватара пользователя


27/01/09
813
Уфа
Alexu007 в сообщении #509468 писал(а):
Функция переводит число из строки символов (коей и являются для процессора десятичные числа - он их совсем не понимает, учить приходится) в шестнадцатиричное в регистре, где с ним можно делать обычные арифметические операции. А вообще - как вы собираетесь писать довольно сложную прогу на ассемблере, если простой функции самостоятельно написать не можете?
Для десятичных цифр в системе команд x86 есть операции с двоично-десятичным кодированием чисел.

 Профиль  
                  
 
 Re: Ввод чисел на ассемблере
Сообщение29.11.2011, 16:05 
Заслуженный участник


27/04/09
28128
Alexu007, вы читать умеете? Вот перечитайте. Там было моё сообщение с программой.

Alexu007 в сообщении #509468 писал(а):
коей и являются для процессора десятичные числа - он их совсем не понимает, учить приходится
Спасибо, кэп.

Chifu в сообщении #509484 писал(а):
Для десятичных цифр в системе команд x86 есть операции с двоично-десятичным кодированием чисел.
Конечно, есть, но уже давным-давно не нужны. Там, точнее, не операции, а команды для корректировки результата, полученного двоичными операциями.

 Профиль  
                  
 
 Re: Ввод чисел на ассемблере
Сообщение29.11.2011, 16:48 
Заслуженный участник


26/07/09
1559
Алматы
2arseniiv
Цитата:
не могли бы вы где-нибудь попытаться скомпилировать вот этот код


Некоторые фрагменты кода конечно непонятны, например
Используется синтаксис ASM
    jmp input_try
    input_try:
 

Мистика? :)

Как я понял, ваш код почему-то не работает... Кстати, извините я не проверял, просто прочитал его и все. Сейчас скачаю masm и посмотрю.

Написан ваш код на masm-совместимом диалекте, что и мой первый пример, но этот диалект я плохо знаю. Например, немного пугают инструкции такого вида mov [bx]+di, ax, такого mov [bx]+di, ax и вот такого mov arrQ+[di], ax. :) Я много экспериментировал с nasm'ом и поэтому имею привычку запиндюривать весь операнд в квадратные скобки. :)

Цитата:
И ещё лень переписать функцию вывода числа, чтобы оно было не задом наперёд.

Ну у вас же есть стек!
код: [ скачать ] [ спрятать ]
Используется синтаксис ASM
itoa proc
    push ax
    mov bx, 10
    xor cx, cx
    rem: xor dx, dx
         div bx
         push dx
         inc cx
         test ax, ax
         jnz rem
    mov ah, 6h
    digit: pop dx
           add dl, '0'
           int 21h
           loop digit
    pop ax
    ret
itoa endp
 

 Профиль  
                  
 
 Re: Ввод чисел на ассемблере
Сообщение29.11.2011, 18:31 
Заслуженный участник


27/04/09
28128
Circiter в сообщении #509696 писал(а):
Мистика? :)
Ой. :oops: Это я переместил ту часть кода снизу наверх, а jmp забыл убрать.

 Профиль  
                  
 
 Re: Ввод чисел на ассемблере
Сообщение30.11.2011, 09:40 
Заслуженный участник


26/07/09
1559
Алматы
2arseniiv
Ага, слил masm, оттранслировал ваш код...

Существенные замечания:
  1. В enter_number нужно сохранять bx (push/pop).
  2. Разберитесь, как правильней написать -- buffer db 8, 7 dup (0) или buffer db 8, 8 dup (0).

Дополнительные замечания и рекомендации:
  1. Рекомендую в assume-директиве на всякий случай связать ss:s (кстати, описывать там cs:code по-моему нафиг не надо).
  2. Вместо простой метки program: наверное лучше описать полноценную подпрограммку program proc far ... program endp (или наоборот -- все подпрограммки заменить на метки :) ).

 Профиль  
                  
 
 Re: Ввод чисел на ассемблере
Сообщение30.11.2011, 16:48 
Заслуженный участник


27/04/09
28128
Так оно у вас работало правильно при запуске? :?

 Профиль  
                  
 
 Re: Ввод чисел на ассемблере
Сообщение01.12.2011, 01:31 
Заслуженный участник


26/07/09
1559
Алматы
Сначала не работало, потом заработало (после внесения описанных выше изменений). Вы уже поняли, почему в подпрограмме enter_number нужно сохранять bx?

 Профиль  
                  
 
 Re: Ввод чисел на ассемблере
Сообщение01.12.2011, 02:30 
Заслуженный участник


27/04/09
28128

(Оффтоп)

Я ещё не смотрел. :? Обязательно посмотрю и перепишу, просто пока закрыт исходник, другое делал.

Просто компилировалось-то у меня сразу, а вот логика не та. Не пробовали вводить числа? (Или вы тоже о ней? Извините, не соображаю, ночь, отчёт, правый глаз отдельно от левого…)

Поглядел на свой код в теме:
Circiter в сообщении #510317 писал(а):
Вы уже поняли, почему в подпрограмме enter_number нужно сохранять bx?
Не понял.

 Профиль  
                  
 
 Re: Ввод чисел на ассемблере
Сообщение01.12.2011, 02:51 
Заслуженный участник


26/07/09
1559
Алматы

(Оффтоп)

2arseniiv
Цитата:
Не пробовали вводить числа?

Я это и имел ввиду, говоря о том, что "заработало". :) Например, ввожу 1 2 3 4 5 1 2 3 4 5 (разделяя enter'ом), программка выплевывает:
Код:
Here is sums, differences, products and quotients:
2 4 6 8 01
0 0 0 0 0
1 4 9 61 52
1 1 1 1 1

Так ведь и должно быть?

Цитата:
Не понял.

Да ерунда. Просто вы почему-то оставили мой код умножения на 10 через сдвиги и сложение. :) А он использует (портит) bx, но этот же регистр используется в enter_array (вызывающем подпрограмму enter_number) для хранения указателя на массив.

Цитата:
правый глаз отдельно от левого

Извините, но правый глаз у всех и всегда отдельно от левого. (впрочем, если вы когда-нибудь для передвижения по городу пользовались т.н. "маршрутками", то мой тезис снимается). :)


-- Чт дек 01, 2011 06:13:59 --

Кстати, даже просто для нахождения поэлементной разности массивоы необходимо снабздить программку возможностью работы с отрицательными числами. Ну и с длиной буфера buffer на всякий случай разберитесь (сейчас у вас типичная уязвимость "переполнение буфера").

 Профиль  
                  
 
 Re: Ввод чисел на ассемблере
Сообщение01.12.2011, 17:31 
Заслуженный участник


27/04/09
28128

(Оффтоп)

Circiter в сообщении #510324 писал(а):
Извините, но правый глаз у всех и всегда отдельно от левого. (впрочем, если вы когда-нибудь для передвижения по городу пользовались т.н. "маршрутками", то мой тезис снимается). :)
И ими тоже.

Спасибо, увидел, наконец, что там используется bx. Как хорошо, что вы нашли! Я, если бы не ленился, тоже бы, наверно, нашёл — просто здесь отступы сбились, а в исходном файле-то всё в порядке, не проворонил бы. :roll:

Думаю, меня не съедят, если сделаю вывод отрицательных чисел без их ввода. :D А про буфер я думал, что нужно в длине учитывать байты длины и возвращённой длины. Не нужно? Вроде бы в книге не оговаривалось.

 Профиль  
                  
 
 Re: Ввод чисел на ассемблере
Сообщение01.12.2011, 23:42 
Заслуженный участник


26/07/09
1559
Алматы
2arseniiv
Цитата:
А про буфер я думал, что нужно в длине учитывать байты длины и возвращённой длины.

Эксперимент прост -- после объявления buffer добавляем сразу после него лишний проверочный байт junk db 0 и смотрим после введения с консоли строк максимальной длины, по прежнему в junk лежит ноль или нет. В вашем случае слишком короткого буфера этот ноль затирается dos'ом. А без этого дополнительного байта junk затираться будет первая ячейка массива arr1. Другое дело, что такие длинные строки соответствуют слишком большим числам, которые ваша программка все-равно пока не переваривает. :)

P.S.: Кажется, там выше я ошибся. Я советовал buffer db 8, 7 dup (0) заменить на buffer db 8, 8 dup (0), но, оказывается, и этого недостаточно -- нужно писать buffer db 8, 9 dup (0). Проверено этим же приемом с junk-байтом. Во всем виноват символ возврата каретки, который dos тоже записывает в буфер (тем не менее, во второй байт буфера кладется фактическое количество полезных символов, без CR'а, поэтому изменять проверку на пустоту строки не требуется, достаточно той test-инструкции).

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 27 ]  На страницу Пред.  1, 2

Модераторы: maxal, Toucan, PAV, Karan, Супермодераторы



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

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


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

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group