|
|
| Посл.отвђт | Сообщенiе |
|
|
Дата: Июл 12, 2004 17:27:41 Правка Понадобилась как-то мне функция перевода числа в строку (в двоичной системе). Заглянул в библиотеку CRT — там такой не оказалось (или плохо смотрел?). Попробовал написать сам. Получилось нечто, преобразующее 32-битное число в 32-символьную строку. Строка монолитная, без разделения на группы по 4 символа (как делает Калькулятор). Потом подумал и сделал 2й вариант, уже с группировкой. Теперь хотелось бы оптимизировать эти варианты по размеру, но и без большого ущерба скорости. В принципе, после можно было бы расширить алгоритм, чтобы обрабатывать не 32 бита, а больше (передавать указатель на исходное число и длину его), хотя моя первая проба получилась несколько корявой, чтобы её расширять, да и не уверен в надобности сего: обычно работа ведётся с DWORD'ами, в крайнем случае - с QWORD'ом. И ещё: чувствую, что со вторым вариантом не совсем гладко, надо бы сделать по-другому. Заранее благодарен за любые замечания! Вот код процедур, а к сообщению прикреплён тестовый код: ;<< eax2binstr ; ; Register to binary string ; arguments: ; eax - number ; edi - pointer to string buffer ; ; modified registers: ; eax,ecx,edx ; ; 11111111111111111111111111111111 eax2binstr: mov edx,eax ; fill buffer by '0' push edi push 8 pop ecx mov eax,'0000' rep stosd dec edi ; process edx bits .lop: mov eax,edx and eax,1 jz .is0 ; if 0 mov byte[edi],'1' ; add 1 .is0: dec edi shr edx,1 jnz .lop pop edi ret ; ;>> eax2binstr ;<< eax2binstr4 ; ; Register to binary string (with character grouping) ; arguments: ; eax - number ; edi - pointer to string buffer ; ; modified registers: ; eax,ecx,edx ; ; 1111 1111 1111 1111 1111 1111 1111 1111 eax2binstr4: ; fill buffer by '0' push edi push eax push 8 push ' ' pop edx pop ecx mov eax,'0000' .fill: mov byte[edi],dl inc edi mov dword[edi],eax add edi,4 dec ecx jnz .fill dec edi pop edx ; process edx bits .lop: mov eax,edx and eax,1 jz .is0 mov byte[edi],'1' ; add '1' if bit = 1 .is0: dec edi inc ecx cmp ecx,4 jne .ngroup dec edi xor ecx,ecx .ngroup: shr edx,1 jnz .lop pop edi ret ; ;>> eax2binstr4 _1733460728__bin2str_test.cmd |
|
|
Дата: Июл 12, 2004 18:27:05 · Поправил: Black_mirroreax2binstr4: mov ecx,8 xchg eax,edx .l0: mov eax,'0000' shr 1 shl edx,1 rcr eax,8 shl edx,1 rcr eax,8 shl edx,1 rcr eax,8 shl edx,1 rcr eax,8 stosd ; mov al,' '; это если на группы нужно разбивать ; stosb loop .l0 ; dec edi;это чтобы лишний пробел убрать ret |
|
|
Дата: Июл 12, 2004 18:34:24 Правка Хм… Красиво — это да. Но минут пять вчитывался — так и не понял, как он работает. Ладно, буду дома медитировать… |
|
|
Дата: Июл 12, 2004 18:40:34 вот так, мне кажется, должно быть меньше: ;<< eax2binstr
;
; Register to binary string
; arguments:
; eax - number
; edi - pointer to string buffer
;
; modified registers:
; eax,ecx,edx
;
; 11111111111111111111111111111111
eax2binstr:
mov edx,eax
mov ecx, 32
; process edx bits
.next_bit:
xor al, al
rcl edx, 1
adc al, '0'
stosb
loop .next_bit
ret
;
;>> eax2binstr |
|
|
Дата: Июл 12, 2004 18:53:53 Первый вариант: ; arguments: ; eax - number ; edi - pointer to string buffer ; ; modified register: ; eax,edx 00401000 F9 stc 00401001 92 xchg eax, edx 00401002 B0 30 mov al, 30 00401004 D1D2 rcl edx, 1 00401006 14 00 adc al, 0 00401008 AA stos [byte es:edi] 00401009 85D2 test edx, edx 0040100B ^ 75 F5 jnz short 2nd.00401002 0040100D 8857 FF mov [byte ds:edi-1], dl |
|
|
Дата: Июл 12, 2004 19:06:11 · Поправил: S_T_A_S_ Да, спасибо за loop :) если использовать ecx на байт меньше 00401000 F9 stc 00401001 91 xchg eax, ecx 00401002 B0 30 mov al, 30 00401004 D1D1 rcl ecx, 1 00401006 14 00 adc al, 0 00401008 AA stos [byte es:edi] 00401009 41 inc ecx 0040100A ^ E2 F6 loopd short 2nd.00401002 0040100C 884F FF mov [byte ds:edi-1], cl ; 0-terminated string |
|
|
Дата: Июл 12, 2004 23:26:17 S_T_A_S_ What the fuflo do you write? ;) Очевидно, таким способом не будут выводится младшие нули... |
|
|
Дата: Июл 12, 2004 23:48:51 captain cobalt Очевидно, таким способом не будут выводится младшие нули... Медитируй дальше 8) |
|
|
Дата: Июл 13, 2004 00:13:33 если размер Очень критичен, то можно сэкономить ещё пару байт :)
;<< eax2binstr
;
; Register to binary string
; arguments:
; eax - number
; edi - pointer to string buffer
;
; modified registers:
; eax,ecx,edx
;
; 11111111111111111111111111111111
eax2binstr:
xchg edx, eax
push 32
pop ecx
; process edx bits
.next_bit:
xor al, al
shl edx, 1
adc al, '0'
stosb
loop .next_bit
ret
|
|
|
Дата: Июл 13, 2004 06:22:37 · Поправил: S_T_A_S_ captain cobalt > What the fuflo do you write? I guess there are some typo errors in the "first-in, last-out" abbreviature =) Вообще-то это простой пример использование флага переноса в качестве счётчика цикла. Вместо лишнего регистра. В качестве недостатков такого подхода можно рассматривать факт, что цикл выполняется 33 раза. Но я взял на себя смелость заодно и завершить строку нулём. (в условии задачи этого не было, но наверняка же придётся делать?) В общем-то можно переделать на цикл с предпроверкой, но тогда код будет весить столько же, сколько в варианте green, единственно, что edx не портится: 00401BE0 F9 stc 00401BE1 91 xchg eax, ecx 00401BE2 B0 30 mov al, 30 00401BE4 D1D1 rcl ecx, 1 00401BE6 E3 05 jecxz short 2nd.00401BED 00401BE8 14 00 adc al, 0 00401BEA AA stos [byte es:edi] 00401BEB ^ EB F5 jmp short 2nd.00401BE2 00401BED C3 retn |
|
|
Дата: Июл 13, 2004 13:23:17 · Поправил: Edmond IceStudent Блин! Смотрел он в CRT. И вообще для кого топик был Int_to_Str? |
|
|
Дата: Июл 14, 2004 19:04:07 Правка Black_mirror green S_T_A_S_ Большое спасибо! Теперь хоть представил свой уровень кодирования… Edmond Гм… Ну, был такой топик. Ну, ужас. А что? Я что ли хуже всех? Между прочим, я всего лишь ученик… |
|
|
Дата: Июл 15, 2004 12:52:59 IceStudent Айс, я приношу свои извенения за недопустимый тон в своём ответе. И прошу не покидать форум WASM.RU, так как он собственно ни в чём не виновен. |