Добрый день. На board.flatassembler.net нашел такой пример Код (Text): Ax2Eax: mov bx, ax and ax, 0F0F0H and bx, 0F0FH shr ax, 4 DB 66H DB 0FH DB 0C8H ; bswap eax mov ax, bx mov bx, 4 .again: cmp al,10 sbb al,69h das DB 66H ;rol eax, 8 rol AX,08H dec bx jnz .again DB 66H ;rol eax, 8 rol AX,08H xchg ah, al Видно,что он использует известный gem: Код (Text): [Convert hex to ASCII] [Assembler][/][8086] This small, and common, gem converts a hexadecimal number into a ASCII value that is possible to put in a string. Since Norbert Juffa brougt the gem to my attention, therefor he will be credited here. He also provided the nice comments. ; ; input: ; al = single hex digit ; ; output: ; al = single ASCII digit ; ; destroys: ; flags ; cmp al,10 ; if x < 10, set CF = 1 sbb al,69h ; 0-9: 96h .. 9Fh, A-F: A1h..A6h das ; 0-9: subtr. 66h -> 30h-39h, ; A-F: subtr. 60h -> 41h..46h Gem writer: Norbert Juffa last updated: 1998-03-16 Результирующий размер кода-38 байт. Можно ли сделать меньше ? Спасибо.
Можно ли сделать меньше ? Конечно, можно. Во-первых, в качестве счетчика цикла использовать CX, а не BX - тогда можно заменить DEC/JNZ на LOOP (-1 байт). Во-вторых, команду mov cx,4 сделать первой в функции - тогда можно заменить shr ax,4 на shr ax,cl (-1 байт). А в-третьих - алгоритм неверный. Если на входе в регистре AX лежит 1234h, то после выполнения mov ax,bx в eax будет 03010204h. Правильный код такой: Код (Text): shl eax,16 mov cx,404h xchg eax,edx @MLoop: shl eax,cl shld eax,edx,cl shl edx,cl cmp al,10 sbb al,69h das dec ch jnz @MLoop (28 байт). На выходе младшая цифра в AL (1234h -> 31323334h). Если нужен обратный порядок, то после цикла нужно добавить bswap eax (+3 байта).
Дополнение: в моем коде можно заменить shl eax,16 / xchg eax,edx на xchg ax,dx / shl edx,16 (-1 байт). Итого: 27 байт.
число в eax на строку указывает esi Код (Text): xor ecx,ecx;2 байта mov cl,8; length of hexstring 2 байта @@A: push eax;1 байт and al,0Fh; mask out high nibble 2 байта cmp al,0Ah;2 байта sbb al,69h;2 байта das;1 байт mov [esi+ecx-1],al; store the asciihex(AL) in the string 4 байта pop eax;1 байт shr eax,4; next nibble;3 байта loop @@A; decrease counter 2 байта Итого 22 байтa
Mikl__ При use16 ко всем командам использующим E?x-регистры добавляется по байту. Итого 27 байт.(но допущение....) Но у меня всеравно хуже - 31 байт: Код (Text): xor CX,CX .0: push AX shr AX,CL AAA jnc numb add AL,11H numb: add AL,30H push CX mov CL,08H DB 66H DB 0FH DB 0ADH DB 0C2H ;shrd edx,eax,cl pop CX pop AX add CL,04H cmp CL,10H jne .0 DB 66H xchg AX,DX ava Сильно.
Otebebe use16 условием не оговаривалось и название должно быть EAX-->ASCII как вариант Код (Text): .data TableASCII db '0123456789ABCDEF' .code mov ebx,offset TableASCII; 5 байт xor ecx,ecx; 2 mov cl,8; 2 @@a: push eax; 1 and al,0Fh; 2 xlat ; 1 mov [esi+ecx],al; 3 pop eax ; 1 shr eax,4 ; 3 loop @@a ; 2 итого 22 байта кода
Mikl__ В таком виде -код=30 байт.Плюс строка.(и допущение-результат не в ЕАX) Говоря use16....не знаю как правильно сказать(начинающий),в общем,если посмотреть в отладчике обязательно будет префикс размера операнда,а для конструкции mov [esi-ecx-1],al префикс размера адреса. (поэтому pop eax =/= 1 байту).
Otebebe Ну раз уж пошел такой табак, то Код (Text): B90800 mov cx,8; length of hexstring 3 байта 50 @@A: push ax;1 байт 240F and al,0Fh; mask out high nibble 2 байта 3C0A cmp al,0Ah;2 байта 1C69 sbb al,69h;2 байта 2F das;1 байт 6788040EFF mov [esi+ecx-1],al; store the asciihex(AL) in the string 5 байт 58 pop ax;1 байт 66C1E804 shr eax,4; next nibble;4 байта E2ED loop @@A; decrease counter 2 байта 66678B06 mov eax,[esi]; 4 байта 27 байт c возвратом результата в EAX, но ради бога, ставь условия четко, про возврат я только что прочитал... и может быть я не понял, нужно было обработать 4 байта? а у меня восемь
Mikl__ Я понял Вы под Windows программируете,да ? Поэтому и нет префиксов 66H. Хорошо.Пусть 22 байта.А теперь из памяти в EAX перенесите,сколько будет ?
use16 условием не оговаривалось То, что код 16-разрядный, понятно из самого кода (по префиксу SIZ). и название должно быть EAX-->ASCII Зачем мелочиться? Название лучше сразу изменить на "Mikl__ - круче всех!!!" > про возврат я только что прочитал А название топика?
ava Зачем ты так? Погляди на свой #4, тоже невнимательно читаешь, уже в названии ASCII[AX]-->EAX мешанина из 32 и 16-битных кодов, где уж мне догадаться...
Mikl__ И строка 10H байт ( в data ).Нее... с xlat не оптимально. Но всеравно спасибо. :-( Что-то мой собственный 31-байтный код косячит. Сорри.
Otebebe Код (Text): B90004 mov cx,4;3 байта 50 @@A: push ax;1 байт 240F and al,0Fh;2 байта 3C0A cmp al,0Ah;2 байта 1C69 sbb al,69h;2 байта 2F das;1 байт 6788440EFF mov [esi+ecx-1],al;5 байт 58 pop ax;1 байт C1E804 shr ax,4;3 байта E2ED loop @@A;2 байта 66AD lodsd;2 байта Итого 24 байта
Mikl__ Cильно! Сам дальше 32 байт не двинулся. Вот: (c рекурсивным вызовом) Код (Text): xor DI,DI A: cmp DI,04H jnz L jmp B L: push AX and al,0Fh cmp al,0Ah sbb al,69h das stosb pop ax shr ax,4 call A ret B: xor SI,SI DB 66H lodsw
Mikl__ A какая разница с точки зрения кол-ва байт ? Что jmp что jz 2 байта,к тому же jmp - хоть куда,а это plus А вообще,конечно рекурсия не нужна -можно уйти джампом на А,но попонтоваться то хочется
Otebebe именно с точки зрения кол-ва байт jnz (2 байта) + jmp (2 байта) = 4 байта, а jz 2 байта, в use32 jcc тоже хоть куда, а не +- 127 байт
Otebebe Не забывай, что эти понты бессмысленно жрут стек и тики так что в 99% случаев рекурсия ни на что кроме понтов не пригодна )