Вывод больших целых чисел

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

  1. IPKILLER

    IPKILLER New Member

    Публикаций:
    0
    Регистрация:
    18 сен 2004
    Сообщения:
    9
    Здравствуйте!



    Я написал вот такую прогу:

    .model small

    .data

    Y db ?

    T db 10

    B db 5



    .code

    begin: mov ax, @data

    mov ds, ax

    mov al, T

    mul B

    aam

    or ah, 30h

    or al, 30h

    mov Y, ah

    mov Y+1, al

    mov Y+2, 24h

    mov ah, 09h

    lea dx, Y

    int 21h

    mov ah, 4ch

    int 21h

    end begin



    В этой проге число 10 умножается на 5 и результат 50 с помощью символьной коррекции выводится на экран. А если у меня при умножении получается 3-х разрядное число, например, 500 или вообще 100000, то как тогда его вывести на экран? (самый простой и понятный для новичка способ)

    Я пробовал, но у меня лезут на экран символы двоеточия.



    Заранее спасибо!
     
  2. readme

    readme New Member

    Публикаций:
    0
    Регистрация:
    2 июл 2005
    Сообщения:
    271
    Адрес:
    Russia
    если тока невдосе то wsprintf самое простое
     
  3. IPKILLER

    IPKILLER New Member

    Публикаций:
    0
    Регистрация:
    18 сен 2004
    Сообщения:
    9
    Нужно в ДОСе.
     
  4. yureckor

    yureckor New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2004
    Сообщения:
    494
    Адрес:
    Russia
    ну так посмотри примеры процедур из пакета MASM'а, там функции типа dwtoa (DWORD to ASCII), переводят число в строку. А строку выводишь на экран средствами ОС.
    Код (Text):
    1.  
    2. ;поддерживает знак
    3. pecreg10 proc chislo:DWORD, mem:DWORD
    4. pushad
    5.  mov edi, [mem]
    6.  mov eax, [chislo]
    7.  
    8.  mov PW [edi], "0"
    9.  test eax,eax
    10.  jz @@kon
    11.  jns @@pos
    12.  mov PW [edi],'-'
    13.  neg eax
    14.  inc edi
    15.  @@pos:      
    16.  
    17.  xor ecx, ecx
    18.  mov ebx, 10
    19.  @@1:
    20.   inc ecx
    21.   xor edx, edx
    22.   div ebx
    23.   push edx
    24.  CP eax, 0, NZ, @@1
    25.  
    26.  @@2:
    27.   pop eax
    28.   add eax, "0"
    29.   mov [edi], al
    30.   inc edi
    31.  dnz ecx, @@2
    32.  
    33. dec edi
    34. @@kon:
    35. inc edi
    36. mov [pecreg_kon], edi
    37. mov PB [edi], 0
    38. stc
    39. popad
    40. ret
    41. pecreg10 endp
    42.  




    PS: CP и dnz макросы.
     
  5. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    IPKILLER

    AAM предназначена для работы с неупакованными BCD-числами, у которых в каждом байте записана одна десятичная цифра от 0 до 9. Она просто делит число в AL на 10 и записывает целую часть в AH, а остаток от деления в AL. Поэтому в твоем коде будут правильно выводиться только результаты <= 99 (9 в AH и 9 в AL), а вот уже для 100 получится AH=10 и AL=0, что при переводе в строку даст ':0'. Для значений < 256 можно просто добавить еще одну AAM: mov al,ah + aam. Но для для больших чисел лучше плюнуть на эту AAM и делать преобразование самому через деление на 10 примерно так как предлагает yureckor (но он как всегда все усложняет своими макросами ;)

    Суть простая: задаешь число байт под строку с запасом например Y db 16 dup(?), грузишь в dx указатель на последний символ Y+16. Затем делишь число в ах(eax) на 10, получаешь в dl остаток, прибавляешь к нему 30h - получаешь код символа, делаешь dec dx и пишешь символ в [dx]. Повторяешь пока число в ax(eax) не станет = 0. В итоге в конце dx у тебя указывает на старшую цифру в строке - грузишь ah и делаешь свой int 21h
     
  6. IPKILLER

    IPKILLER New Member

    Публикаций:
    0
    Регистрация:
    18 сен 2004
    Сообщения:
    9
    А если я число ввожу с клавиатуры и оно соответственно заносится в буфер, например, buf , то как тогда быть. Ведь число должно находиться в AX. Его как-то нужно скопировать из buf в регистр AX, чтобы дальше производить деление содержимого AX на 10 и т.д.... Я пробовал просто mov ax, buf, но это не действует.
     
  7. yureckor

    yureckor New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2004
    Сообщения:
    494
    Адрес:
    Russia
    IPKILLER

    тогда тебе нужно процедуру перевода текста в число.

    См. опять тот же масм
    Код (Text):
    1.  
    2. a2dw proc uses ecx edi edx esi String:DWORD
    3.  
    4.       ;----------------------------------------
    5.       ; Convert decimal string into dword value
    6.       ; return value in eax
    7.       ;----------------------------------------
    8.  
    9.       xor ecx, ecx
    10.       mov edi, String
    11.       invoke lstrlen, String
    12.  
    13.       .while eax != 0
    14.         xor edx, edx
    15.         mov dl, byte ptr [edi]
    16.         sub dl, "0" ; subtrack each digit with "0" to convert it to hex value
    17.         mov esi, eax
    18.         dec esi
    19.         push eax
    20.         mov eax, edx
    21.         push ebx
    22.         mov ebx, 10
    23.           .while esi > 0
    24.             mul ebx
    25.             dec esi
    26.           .endw
    27.         pop ebx
    28.         add ecx, eax
    29.         pop eax
    30.         inc edi
    31.         dec eax
    32.       .endw
    33.  
    34.         mov eax, ecx
    35.         ret
    36.  
    37. a2dw endp
    38.  
     
  8. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    yureckor

    Ты где такую реализацию откопал 8(

    См. atodw.asm и atol.asm в m32lib

    Вроде длину строки никогда специально не ищут (код сам вываливается если не цифра) и умножение всегда делают через lea, а у тебя еще и пуши\попы какие-то... Как советуют отцы: "учите матчасть" ;)