(FASM)Сложение и вывод результата на экран

Тема в разделе "WASM.BEGINNERS", создана пользователем krundetz, 25 апр 2007.

  1. krundetz

    krundetz Alexander

    Публикаций:
    0
    Регистрация:
    25 апр 2007
    Сообщения:
    5
    Адрес:
    N.Novgorod
    Только начал изучать ассемблер. Сталкнулся с тем что не могу
    вывести результат сложения на экран.
    Вот что смог сделать сам:
    Код (Text):
    1. org     256
    2.         mov     ah, 9
    3.         mov     dx, text
    4.         int     21h
    5.         mov     ah,2
    6.         mov     dl, '9'
    7.         add     dl, 1
    8.         int     21h
    9.         mov     ah, 1
    10.         int     21h
    11.         int     20h
    12. text     db      'Result add = $'
    Представил 9 как строку и прибавил к ней 1, получил следуюший
    за девятью символ ":". Если изменить пример и в dl помешать 9 или 9h
    и прибавлять 1 или 1h то получаем переход в начало следующий строки.
    Мне хотелось бы чтобы выводилось не соответствие 16-тиричным цифрам
    из таблицы символов, а результат сложения тоесть: 9 + 1 = 10 ,
    25 + 30 = 55 , 101 + 280 = 381 и т.п. Подскажите пожалуйста как это
    сделать. Заранее спасибо.
     
  2. q_q

    q_q New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2003
    Сообщения:
    1.706
    krundetz
    Суммируй числа, результат преобразуй в строку и выводи ее на экран.
     
  3. krundetz

    krundetz Alexander

    Публикаций:
    0
    Регистрация:
    25 апр 2007
    Сообщения:
    5
    Адрес:
    N.Novgorod
    А можно небольшой примерчик.
     
  4. q_q

    q_q New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2003
    Сообщения:
    1.706
    krundetz
    Команду процессора add ты знаешь.
    Вывод на экран строки при помощи int21h ah=9 ты знаешь.

    Осталось преобразовать число в строку.

    Рассмотрим вариант, когда строка должна содержать десятичное представление целого положительного числа.
    Для преобразования числа от 0 до 9 в символ к нему надо прибавить 30h (символ '0').
    Преобразование числа больше 9 в строку сводится к делению его на 10, (в остатке получается число от 0 до 9, которое преобразовывать мы уже умеем) до тех пор, пока оно не станет равным нулю.
    Некоторое неудобство в том, что строка строится задом наперед.

    ps продемонстрируй свою заинтересованность в решении вопроса.
     
  5. Vov4ick

    Vov4ick Владимир

    Публикаций:
    0
    Регистрация:
    8 окт 2006
    Сообщения:
    581
    Адрес:
    МО
    А пример ассемблируется?
    mov dx,offset text <- помещаем в dx адрес начала строки.
     
  6. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Код (Text):
    1. ;
    2. ; void itoa( buffer, value, radix, 0x00XX00YY );  // XX - letter to fill, YY - number of fills
    3. ;
    4.  
    5. itoa:
    6.    mov  ebx, [esp+12]  ; radix
    7.    mov  eax, [esp+8]   ; value
    8.    mov  edi, [esp+4]   ; buffer
    9.    xor  ecx, ecx       ; счетчик
    10.  
    11.    ; последовательное деление
    12.   _div:
    13.    xor  edx, edx       ; старшая часть делимого, всегда 0
    14.  
    15.    div  ebx            ; EDX:EAX / EBX
    16.  
    17.    mov  dl, byte [edx+small_table]  ; лукап символа по таблице, остаток - индекс
    18.    mov  byte [edi], dl
    19.  
    20.    inc  edi            ; инкремент указателя
    21.    inc  ecx            ; инкремент счетчика
    22.  
    23.    test eax, eax       ; частное = 0 ?
    24.    jz   _q             ; да, закончили деление
    25.  
    26.    jmp _div
    27.   _q:
    28.  
    29.    mov  ax, [esp+16]
    30.    movzx eax, ax
    31.    .if  eax,ne,0
    32.      .while ecx,l,eax
    33.        mov  bl, [esp+18]
    34.        mov  byte [edi], bl
    35.        inc  edi
    36.        inc  ecx
    37.      .endw
    38.    .endif
    39.  
    40.    mov  byte [edi], 0
    41.  
    42.    ; переворот строки
    43.    mov  edi, [esp+4]   ; переходим снова в начало буфера
    44.    mov  edx, ecx       ; копируем число символов
    45.   _r:                  ; цикл реверса буфера
    46.    mov  al, byte [edi+ecx-1]     ; загружаем левый байт
    47.    mov  esi, edx
    48.    sub  esi, ecx
    49.    mov  ah, byte [edi+esi]       ; загружаем правый байт
    50.  
    51.    cmp  ecx, esi                 ; хватит?
    52.    jna _qq
    53.  
    54.    mov  byte [edi+ecx-1], ah     ; меняем местами
    55.    mov  byte [edi+esi], al
    56.  
    57.    loop _r
    58.   _qq:
    59.  
    60.    ret  16
    61. small_table db '0123456789abcdefghijklmnopqrstuvwxyz'
     
  7. q_q

    q_q New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2003
    Сообщения:
    1.706
    Vov4ick
    см. заголовок темы - fasm.
     
  8. q_q

    q_q New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2003
    Сообщения:
    1.706
    Great
    Код (Text):
    1. ...
    2.    test eax, eax       ; частное = 0 ?
    3.    jz   _q             ; да, закончили деление
    4.  
    5.    jmp _div
    6.   _q:
    7. ...
    Почему бы не заменить на
    Код (Text):
    1. ...
    2.    test eax, eax       ; частное = 0 ?
    3.    jnz  _div             ; нет, продолжаем деление
    4. ...
     
  9. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    q_q
    хе. я это писал глубокой ночью и както мне было пофиг, работает и работает)
     
  10. q_q

    q_q New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2003
    Сообщения:
    1.706
    Great
    мне было пофиг
    До сих пор?
    Человек пишит под dos, а ты ему 32-ух битную адресацию. :dntknw:
     
  11. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    хм. ну вообще-то можно использовать 32битные регистры в реальном режиме, никто не запрещает) тока есесно у каждой команды будет по префиксу и размер кода будет побольше, чем 32битный (настоящий) аналог
     
  12. q_q

    q_q New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2003
    Сообщения:
    1.706
    Great
    Я про _адресацию_ буфера приемника.
     
  13. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    а-а. ну значит не судьба)
     
  14. Vov4ick

    Vov4ick Владимир

    Публикаций:
    0
    Регистрация:
    8 окт 2006
    Сообщения:
    581
    Адрес:
    МО
    Ужос! Не знал.
    Мой вариант. Писал очень давно, но часто спользуется.
    Код (Text):
    1. num2ascii       proc    near
    2. ; AX - число   ES:DI-куда писать ответ
    3.                 std                ; Запись справа налево для STOSB
    4.                 mov     bx,10      ; Делитель
    5. diving:
    6.                 xor     dx,dx      ; Чтобы избежать переполнения при делении
    7.                 div     bx         ; AX=частное DX=остаток
    8.                                    ; DX=DL % 10
    9.                 push    ax
    10.                 mov     ax,dx
    11.  
    12.                 add     al,'0'
    13.                 stosb              ; AX -> [ES:DI] ; DEC DI
    14.  
    15.                 pop     ax
    16.                 or      ax,ax      ; Частное было равно нулю?
    17.                 jnz     diving     ; Нет-продолжить цикл
    18.                 ret
    19. num2ascii       endp
     
  15. Arthur

    Arthur New Member

    Публикаций:
    0
    Регистрация:
    27 янв 2007
    Сообщения:
    494
    Vov4ick
    вместо add al,'0', лучше or al,'0', логика быстрее арифметики :)
    Да к стате чтобы узнать какое число (положительное илил отрицательное) нужно проверить 31 бит(для 32-Bit) и 15 бит(для 16-bit). Если он равен 1 значить число отрицательное, если 0 то положительное.

    Чтобы проверить(не затронув состояние регистра) моно так:
    Код (Text):
    1.    bt ax,15
    2.    jae next
    3.    mov [str1], '-'
    4. next:  
    5.    ...
    Правда этот пример будет работать на процах не ниже 80386.
     
  16. asd

    asd New Member

    Публикаций:
    0
    Регистрация:
    12 мар 2005
    Сообщения:
    952
    Адрес:
    Russia
    Лучше так:
    or ax,ax
    js label - отрицательное
     
  17. Arthur

    Arthur New Member

    Публикаций:
    0
    Регистрация:
    27 янв 2007
    Сообщения:
    494
    asd мда совсем забыл про SF флаг, указывающий на знак. далее можно использовать команду neg, чтобы обратить число в положительное, и проделать все то,
    что Vov4ick написал.

    И если я неошибаюсь, то процессор будет тратить по одному дополнительному такту.
     
  18. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    Arthur
    Мне почему то кажется, что вывод чисел на экран не критичная ко времени операция ;)
     
  19. AsmGuru62

    AsmGuru62 Member

    Публикаций:
    0
    Регистрация:
    12 сен 2002
    Сообщения:
    689
    Адрес:
    Toronto
    n0name
    Наверное, зависит от программы. Если компилятору надо всю ночь компилиривать например: сколько значений в разных форматах надо вывести на консоль?..
     
  20. asd

    asd New Member

    Публикаций:
    0
    Регистрация:
    12 мар 2005
    Сообщения:
    952
    Адрес:
    Russia
    Процедура вывода числа на экран занимала 100 тактов. После оптимизации её скорость возросла на 10 процентв. Вопрос на сколько поднимится производительность труда одепта?