Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Asm: Общие вопросы > ESI, EDI - почему они?


Автор: stab 7.7.2007, 12:34
в исходниках часто вижу такое: авторы пытаются использовать ESI, EDI при организации циклов чтения\записи\копирования, принося в жертву работу на регистрах без использования стека. в самом теле цикла нет ни комманд с префиксом rep, ни комманд вроде movsb, т.е. что-то вроде:

Код

; IN: EAX = src, EDX = dst, ECX = count
push    ESI
push    EDI

mov    ESI, EAX
mov    EDI, EDX

loop:
mov    EAX, [ESI]
mov    [EDI], EAX

add    ESI, 4
add    EDI, 4
dec    ECX
jnz    loop

pop    EDI
pop    ESI
ret


исходники довольно новые, датированы нашим веком smile состояние регистров EAX, EDX, ECX после выхода из процедуры никого воздействия на дальнейшую работу не имеет, т.е. их смело можно менять как душе угодно. в чём же смысл этого подхода с EDI\ESI?

з.ы. форум по асму вообще жив? )

Автор: Kuvaldis 7.7.2007, 13:02
stab, 
Как я понимаю: тут сделано простое "ручное" movsd, причем оно медленнее работает (нет аппаратной поддержки), больше по коду (смотрим формат машинной команды) да и вообще не эстетично

ВЫВОД: такой подход от незнания команд

Добавлено через 1 минуту и 31 секунду
А так как код ЯВНО 32-битный, то вместо esi/edi можно использовать любой из регистров общего назначения.

Автор: stab 7.7.2007, 13:18
дело в том, что код делался какими-то вроде как гуру, оптимизации под MMX, SSE, т.д. вот я и задумался, может они что-то знают чего не знаем мы?

з.ы. для меня критична именно скорость работы..

Автор: W4FhLF 7.7.2007, 14:37
Цитата(Kuvaldis @  7.7.2007,  13:02 Найти цитируемый пост)
причем оно медленнее работает (нет аппаратной поддержки)


Обоснуйте. Люди съевшие собаку на оптимизации с таким мнением несогласны. Для какого процессора и на основании чего делались выводы? 

Автор: Kuvaldis 7.7.2007, 14:53
W4FhLF, 
Цитата

Обоснуйте. Люди съевшие собаку на оптимизации с таким мнением несогласны. Для какого процессора и на основании чего делались выводы? 

А для чего в архитектуру INTEL были введены строковые команды? ИМХО, все, что делается на аппаратном уровне, должно выполняться быстрее. Даже в универе как-то тестили ради интереса похожие вещи (не хотелось верить, что строковые команды лучше) 

Кстати, как я понимаю, именно поэтому например, сохранение регистров и т.д. при переключении задач стараются делать на аппаратном уровне.

НО! Я могу и ошибаться. Если я не прав, то с удовольствием выслушаю компетентное мнение.

Автор: W4FhLF 7.7.2007, 15:27
Цитата(Kuvaldis @  7.7.2007,  14:53 Найти цитируемый пост)
А для чего в архитектуру INTEL были введены строковые команды?


Нет, ну хороший вопрос smile Видимо, для удобства. 

Цитата(Kuvaldis @  7.7.2007,  14:53 Найти цитируемый пост)
МХО, все, что делается на аппаратном уровне, должно выполняться быстрее.


Что ты имеешь ввиду? А обычные команды они как по-твоему выполняются? Не ОС же их эмулирует. 


Для маленьких буферов(кб) movsd наверное самый лучший вариант, ну а для больших существуют более эффективные варианты. В вышеприведённой функции можно, например, развернуть цикл в два раза и уже получишь выигрыш(хотя бы потому что число кеш-промахов сократиться). 

Например:
Код

    mov     esi,src
            mov     edi,dest
            mov     ecx,size_of_byte
            cmp     ecx,4
            jl      b_c
            sub     ecx,4
         @@:   
            mov     eax,[esi+ecx]
            mov     [edi+ecx],eax
            sub     ecx,4
            js      @F
            mov     eax,[esi+ecx]
            mov     [edi+ecx],eax
            sub     ecx,4
            jns     @B
         @@:
            add     ecx,4
        b_c:    
            jz      _end
         @@:
            mov     al,[esi+ecx-1]
            mov     [edi+ecx-1],al
            dec     ecx
            jnz     @B
        _end:


Или, немножко из другой области, но всё же приведу:
Код

;================================================================================
;   Процедура копирования строки
;   Возвращаемое значение: eax==длина скопированной строки
;   

align 16
cr_strcpy proc lpDest:DWORD, lpSource:DWORD
    option prologue : none
    option epilogue : none
    
    push    esi
    push    edi

    mov     esi,[esp+16]
    mov     edi,[esp+12]
    jmp     _test_align
    
align 16
 @@:
    mov     al,[esi]
    mov     [edi],al
    add     esi,1
    add     edi,1
    test    al,al
    jz      @ret
_test_align:
    test    esi,3h
    jnz     @B
_st:    
    sub     esi,4
    sub     edi,4
    jmp     _loop
    
align 16
_last:
    mov     al,[esi]                ;копирование последних 0...3 байт
    inc     esi
    mov     [edi],al
    inc     edi
    test    al,al                   ;
    jnz     _last
@ret:    
    lea     eax,[esi-1]
    sub     eax,[esp+16]            ;кол-во скопированных (длина строки)
    pop     edi
    pop     esi
    retn    8
    
align 16
_copy:
    mov     [edi],edx               ;если не конец, сохраняем дворд
_loop:

    add     esi,4
    add     edi,4
    mov     eax,[esi]               ;дворд из первой строки;lea     ecx,[eax-01010101h]     ;вычитаем из каждого байта 1, если был ноль, то будет FFh
    mov     ecx,-01010101h
    mov     edx,eax                 ;загружаем для копирования
    add     ecx,eax
    not     eax                     ;инвертируем, если был ноль будет FFh
    and     ecx,eax                 ;and : если был ноль, на его месте будет FFh
    and     ecx,80808080h           ;на месте исходного нулевого байта будет 80h, в остальных - ноль
    jz      _copy
    jmp     _last                   ;если не ноль (один из байтов = 80h) - конец строки

    
    option prologue : prologuedef
    option epilogue : epiloguedef
    
cr_strcpy endp


http://www.insidepro.com/kk/024/024r.shtml (причём обрати внимание насколько разняться результаты для разных процессоров, так, что единую формулу вывести невозможно)

Автор: stab 8.7.2007, 06:45
W4FhLF, мой вопрос был скорее в том, почему авторы выбрали для работы ESI, EDI, ECX, вместо оригинальных EAX, EDX, ECX.

Автор: dumb 8.7.2007, 13:23
Цитата(stab @  8.7.2007,  07:45 Найти цитируемый пост)
почему авторы выбрали для работы ESI, EDI, ECX, вместо оригинальных EAX, EDX, ECX. 

потому что "оригинальных" просто не хватает для такой реализации. eax - обменник, ecx - счетчик, нужно еще два для src-dst, а у тебя только edx остался. а коль уж все равно сохраняться, то почему не сделать все через привычные "строковые" регистры?
также не исключен вариант "недо-переделки": автор просто заменил rep movsd на "ручной" цикл, а "обвеску" менять не стал... 

Автор: Kuvaldis 8.7.2007, 15:16
W4FhLF, 
Сиба за инфу smile Есть мне в чем еще разбираться. +1

Автор: Kuvaldis 8.7.2007, 15:35
кстати, полезная ссылка:
http://www.rsdn.ru/Forum/message/18426.flat.aspx

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)