2014 dxdy logo

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

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




На страницу Пред.  1, 2
 
 Re: Ввод чисел на ассемблере
Сообщение29.11.2011, 04:04 
Внесу и я свою посильную лепту, когда-то тож кодил на ассемблере. Функция переводит число из строки символов (коей и являются для процессора десятичные числа - он их совсем не понимает, учить приходится) в шестнадцатиричное в регистре, где с ним можно делать обычные арифметические операции. А вообще - как вы собираетесь писать довольно сложную прогу на ассемблере, если простой функции самостоятельно написать не можете?


Код:
;Процедура переводит число из 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 
Аватара пользователя
Alexu007 в сообщении #509468 писал(а):
Функция переводит число из строки символов (коей и являются для процессора десятичные числа - он их совсем не понимает, учить приходится) в шестнадцатиричное в регистре, где с ним можно делать обычные арифметические операции. А вообще - как вы собираетесь писать довольно сложную прогу на ассемблере, если простой функции самостоятельно написать не можете?
Для десятичных цифр в системе команд x86 есть операции с двоично-десятичным кодированием чисел.

 
 
 
 Re: Ввод чисел на ассемблере
Сообщение29.11.2011, 16:05 
Alexu007, вы читать умеете? Вот перечитайте. Там было моё сообщение с программой.

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

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

 
 
 
 Re: Ввод чисел на ассемблере
Сообщение29.11.2011, 16:48 
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 
Circiter в сообщении #509696 писал(а):
Мистика? :)
Ой. :oops: Это я переместил ту часть кода снизу наверх, а jmp забыл убрать.

 
 
 
 Re: Ввод чисел на ассемблере
Сообщение30.11.2011, 09:40 
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 
Так оно у вас работало правильно при запуске? :?

 
 
 
 Re: Ввод чисел на ассемблере
Сообщение01.12.2011, 01:31 
Сначала не работало, потом заработало (после внесения описанных выше изменений). Вы уже поняли, почему в подпрограмме enter_number нужно сохранять bx?

 
 
 
 Re: Ввод чисел на ассемблере
Сообщение01.12.2011, 02:30 

(Оффтоп)

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

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

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

 
 
 
 Re: Ввод чисел на ассемблере
Сообщение01.12.2011, 02:51 

(Оффтоп)

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 

(Оффтоп)

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

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

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

 
 
 
 Re: Ввод чисел на ассемблере
Сообщение01.12.2011, 23:42 
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


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group