ASCII[AX]-->EAX

Тема в разделе "WASM.A&O", создана пользователем Otebebe, 10 май 2007.

  1. Otebebe

    Otebebe New Member

    Публикаций:
    0
    Регистрация:
    3 апр 2006
    Сообщения:
    91
    Добрый день.

    На board.flatassembler.net
    нашел такой пример
    Код (Text):
    1. Ax2Eax:
    2.  
    3.        mov bx, ax
    4.        and ax, 0F0F0H
    5.        and bx, 0F0FH
    6.        shr ax, 4
    7.        DB 66H
    8.        DB 0FH
    9.        DB 0C8H                   ; bswap eax
    10.        mov ax, bx
    11.  
    12.  
    13.        mov bx, 4
    14.         .again:
    15.                
    16.                 cmp al,10
    17.                 sbb al,69h
    18.                 das
    19.                 DB 66H           ;rol eax, 8
    20.                 rol AX,08H
    21.                 dec bx
    22.                 jnz .again
    23.         DB 66H                   ;rol eax, 8
    24.         rol AX,08H
    25.         xchg ah, al
    Видно,что он использует известный gem:
    Код (Text):
    1. [Convert hex to ASCII]                                 [Assembler][/][8086]
    2.  
    3. This small, and common, gem converts a hexadecimal number into a ASCII
    4. value that is possible to put in a string. Since Norbert Juffa brougt the
    5. gem to my attention, therefor he will be credited here. He also provided
    6. the nice comments.
    7.  
    8. ;
    9. ; input:
    10. ;   al = single hex digit
    11. ;
    12. ; output:
    13. ;   al = single ASCII digit
    14. ;
    15. ; destroys:
    16. ;   flags
    17. ;
    18.  
    19.         cmp     al,10           ; if x < 10, set CF = 1
    20.         sbb     al,69h          ; 0-9: 96h .. 9Fh,  A-F: A1h..A6h
    21.         das                     ; 0-9: subtr. 66h -> 30h-39h,
    22.                                 ; A-F: subtr. 60h -> 41h..46h
    23.  
    24.                                                   Gem writer: Norbert Juffa
    25.                                                    last updated: 1998-03-16
    Результирующий размер кода-38 байт.

    Можно ли сделать меньше ?
    Спасибо.
     
  2. ava

    ava New Member

    Публикаций:
    0
    Регистрация:
    11 окт 2003
    Сообщения:
    169
    Можно ли сделать меньше ?

    Конечно, можно.

    Во-первых, в качестве счетчика цикла использовать CX, а не BX - тогда можно заменить DEC/JNZ на LOOP (-1 байт).
    Во-вторых, команду mov cx,4 сделать первой в функции - тогда можно заменить shr ax,4 на shr ax,cl (-1 байт).

    А в-третьих - алгоритм неверный. Если на входе в регистре AX лежит 1234h, то после выполнения mov ax,bx в eax будет 03010204h.

    Правильный код такой:
    Код (Text):
    1.         shl eax,16
    2.         mov cx,404h
    3.         xchg    eax,edx
    4.  
    5. @MLoop:
    6.         shl eax,cl
    7.         shld    eax,edx,cl
    8.         shl edx,cl
    9.  
    10.         cmp al,10
    11.         sbb al,69h
    12.         das
    13.  
    14.         dec ch
    15.         jnz @MLoop
    (28 байт). На выходе младшая цифра в AL (1234h -> 31323334h). Если нужен обратный порядок, то после цикла нужно добавить bswap eax (+3 байта).
     
  3. Otebebe

    Otebebe New Member

    Публикаций:
    0
    Регистрация:
    3 апр 2006
    Сообщения:
    91
    ava
    Cпасибо.
     
  4. ava

    ava New Member

    Публикаций:
    0
    Регистрация:
    11 окт 2003
    Сообщения:
    169
    Беру обратно замечание насчет неверного кода.
    Код верный, я просто не заметил фиксап после цикла.
     
  5. ava

    ava New Member

    Публикаций:
    0
    Регистрация:
    11 окт 2003
    Сообщения:
    169
    Дополнение: в моем коде можно заменить shl eax,16 / xchg eax,edx на xchg ax,dx / shl edx,16 (-1 байт). Итого: 27 байт.
     
  6. Mikl_

    Mikl_ New Member

    Публикаций:
    0
    Регистрация:
    14 ноя 2006
    Сообщения:
    907
    число в eax на строку указывает esi
    Код (Text):
    1.     xor ecx,ecx;2 байта
    2.              mov cl,8; length of hexstring 2 байта
    3. @@A:    push eax;1 байт
    4.     and al,0Fh; mask out high nibble 2 байта
    5.     cmp al,0Ah;2 байта
    6.     sbb al,69h;2 байта
    7.     das;1 байт
    8.     mov [esi+ecx-1],al; store the asciihex(AL) in the string 4 байта
    9.     pop eax;1 байт
    10.     shr eax,4; next nibble;3 байта
    11.     loop @@A; decrease counter 2 байта
    Итого 22 байтa
     
  7. Otebebe

    Otebebe New Member

    Публикаций:
    0
    Регистрация:
    3 апр 2006
    Сообщения:
    91
    Mikl__
    При use16 ко всем командам использующим E?x-регистры добавляется по байту.
    Итого 27 байт.(но допущение....)
    Но у меня всеравно хуже - 31 байт:

    Код (Text):
    1. xor CX,CX
    2.  
    3. .0:
    4. push AX
    5. shr AX,CL
    6. AAA
    7. jnc numb
    8. add AL,11H
    9. numb:
    10. add AL,30H
    11.  
    12. push CX
    13. mov CL,08H
    14. DB 66H
    15. DB 0FH
    16. DB 0ADH
    17. DB 0C2H        ;shrd edx,eax,cl
    18.  
    19. pop CX
    20. pop AX
    21. add CL,04H
    22. cmp CL,10H
    23. jne .0
    24. DB 66H
    25. xchg AX,DX
    ava
    Сильно.
     
  8. Mikl_

    Mikl_ New Member

    Публикаций:
    0
    Регистрация:
    14 ноя 2006
    Сообщения:
    907
    Otebebe
    use16 условием не оговаривалось и название должно быть EAX-->ASCII
    как вариант
    Код (Text):
    1. .data
    2. TableASCII db '0123456789ABCDEF'
    3. .code
    4.          mov ebx,offset TableASCII; 5 байт
    5.          xor ecx,ecx;                     2
    6.          mov cl,8;                         2
    7. @@a: push eax;                        1
    8.          and al,0Fh;                      2                      
    9.          xlat      ;                         1  
    10.          mov [esi+ecx],al;              3
    11.          pop eax                ;          1
    12.          shr eax,4               ;         3
    13.          loop @@a              ;           2
    итого 22 байта кода
     
  9. Otebebe

    Otebebe New Member

    Публикаций:
    0
    Регистрация:
    3 апр 2006
    Сообщения:
    91
    Mikl__
    В таком виде -код=30 байт.Плюс строка.(и допущение-результат не в ЕАX)
    Говоря use16....не знаю как правильно сказать(начинающий),в общем,если посмотреть в отладчике
    обязательно будет префикс размера операнда,а для конструкции mov [esi-ecx-1],al префикс размера адреса. (поэтому pop eax =/= 1 байту).
     
  10. Mikl_

    Mikl_ New Member

    Публикаций:
    0
    Регистрация:
    14 ноя 2006
    Сообщения:
    907
    Otebebe
    Ну раз уж пошел такой табак, то
    Код (Text):
    1.     B90800 mov cx,8; length of hexstring 3 байта
    2.              50       @@A: push ax;1 байт
    3.     240F     and al,0Fh; mask out high nibble 2 байта
    4.     3C0A     cmp al,0Ah;2 байта
    5.     1C69     sbb al,69h;2 байта
    6.     2F         das;1 байт
    7.     6788040EFF mov [esi+ecx-1],al; store the asciihex(AL) in the string 5 байт
    8.     58         pop ax;1 байт
    9.     66C1E804 shr eax,4; next nibble;4 байта
    10.     E2ED      loop @@A; decrease counter 2 байта
    11.              66678B06 mov eax,[esi]; 4 байта
    27 байт c возвратом результата в EAX, но ради бога, ставь условия четко, про возврат я только что прочитал... и может быть я не понял, нужно было обработать 4 байта? а у меня восемь
     
  11. Otebebe

    Otebebe New Member

    Публикаций:
    0
    Регистрация:
    3 апр 2006
    Сообщения:
    91
    Mikl__
    Я понял :) Вы под Windows программируете,да ? Поэтому и нет префиксов 66H.
    Хорошо.Пусть 22 байта.А теперь из памяти в EAX перенесите,сколько будет ?
     
  12. ava

    ava New Member

    Публикаций:
    0
    Регистрация:
    11 окт 2003
    Сообщения:
    169
    use16 условием не оговаривалось

    То, что код 16-разрядный, понятно из самого кода (по префиксу SIZ).

    и название должно быть EAX-->ASCII

    Зачем мелочиться? Название лучше сразу изменить на "Mikl__ - круче всех!!!" >:)

    про возврат я только что прочитал

    А название топика?
     
  13. Mikl_

    Mikl_ New Member

    Публикаций:
    0
    Регистрация:
    14 ноя 2006
    Сообщения:
    907
    ava
    Зачем ты так? Погляди на свой #4, тоже невнимательно читаешь, уже в названии ASCII[AX]-->EAX мешанина из 32 и 16-битных кодов, где уж мне догадаться...
     
  14. Otebebe

    Otebebe New Member

    Публикаций:
    0
    Регистрация:
    3 апр 2006
    Сообщения:
    91
    Mikl__
    И строка 10H байт ( в data ).Нее... с xlat не оптимально.
    Но всеравно спасибо.

    :-(
    Что-то мой собственный 31-байтный код косячит.
    Сорри.
     
  15. Mikl_

    Mikl_ New Member

    Публикаций:
    0
    Регистрация:
    14 ноя 2006
    Сообщения:
    907
    Otebebe
    Код (Text):
    1. B90004       mov cx,4;3 байта
    2. 50       @@A: push ax;1 байт
    3. 240F         and al,0Fh;2 байта
    4. 3C0A         cmp al,0Ah;2 байта
    5. 1C69         sbb al,69h;2 байта
    6. 2F       das;1 байт
    7. 6788440EFF   mov [esi+ecx-1],al;5 байт
    8. 58       pop ax;1 байт
    9. C1E804       shr ax,4;3 байта
    10. E2ED         loop @@A;2 байта
    11. 66AD         lodsd;2 байта
    Итого 24 байта
     
  16. Otebebe

    Otebebe New Member

    Публикаций:
    0
    Регистрация:
    3 апр 2006
    Сообщения:
    91
    Mikl__
    Cильно!
    Сам дальше 32 байт не двинулся.
    Вот: (c рекурсивным вызовом)

    Код (Text):
    1. xor DI,DI
    2.  
    3. A:
    4. cmp DI,04H
    5.  jnz L
    6.  jmp B
    7. L:
    8. push AX
    9. and al,0Fh
    10. cmp al,0Ah
    11. sbb al,69h
    12.  das
    13. stosb
    14. pop ax
    15. shr ax,4
    16. call A
    17.  ret
    18. B:
    19. xor SI,SI
    20. DB 66H
    21. lodsw
     
  17. Mikl_

    Mikl_ New Member

    Публикаций:
    0
    Регистрация:
    14 ноя 2006
    Сообщения:
    907
    Otebebe
    не есть Gud если растояние до B менее 127 байт
    jnz L
    jmp B
    L:
    нужно
    jz B
     
  18. Otebebe

    Otebebe New Member

    Публикаций:
    0
    Регистрация:
    3 апр 2006
    Сообщения:
    91
    Mikl__
    A какая разница с точки зрения кол-ва байт ? Что jmp что jz 2 байта,к тому же
    jmp - хоть куда,а это plus
    А вообще,конечно рекурсия не нужна -можно уйти джампом на А,но попонтоваться то хочется :)
     
  19. Mikl_

    Mikl_ New Member

    Публикаций:
    0
    Регистрация:
    14 ноя 2006
    Сообщения:
    907
    Otebebe
    именно с точки зрения кол-ва байт jnz (2 байта) + jmp (2 байта) = 4 байта, а jz 2 байта, в use32 jcc тоже хоть куда, а не +- 127 байт
     
  20. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    Otebebe
    Не забывай, что эти понты бессмысленно жрут стек и тики ;) так что в 99% случаев рекурсия ни на что кроме понтов не пригодна ;))