Size: a a a

Ассемблер

2021 August 11

d

disba1ancer in Ассемблер
зато если не пользоваться push/pop и заранее выделить место на стеке, можно освободить целый регистр
источник

ST

Saenro T in Ассемблер
Попробуй оптимизировать
источник

D

Den in Ассемблер
ну как минимум можно сразу записать mov ebx, eax и mov edi, eax тогда со стеком не надо работать :)
источник

E

Entusiast in Ассемблер
Действительно, rep movs, stos - работают быстро.
Однако! Это не относится к scas, cmps
Для больших данных на современных процессорах rep scasb выполняется 2 цикла на байт.

Использовать CMP+JNE в данном случае лучше:
betterLenStr:
 push  edi

 xor  eax, eax
 mov  edi, dword[esp+8]
@@:  add  eax, 1
 cmp  byte[edi], 0x00
 jne  @b

 pop  edi
 ret

Можно ещё задействовать VCMPEQB
источник

s

s54816 in Ассемблер
Ну и что, что сломали логику, зато оптимизировали! Оригинал возвращает значение в ebx (вот такие странные люди, да) и не учитывает ноль на конце.
источник

E

Entusiast in Ассемблер
Я не писал аналог кода сверху.

Это отдельный код, демонстрирующий суть замены SCAS

Если нужен учёт нуля, и возврат в EBX:
betterLenStr:
 push edi
 
 xor  ebx, ebx ; Возврат в EBX
 mov  edi, dword[esp+8]
@@:  
 ; EAX/EBX
 add  ebx, 1
 cmp  byte[edi], 0x00
 jne  @b
 
sub  ebx, 1 ; Убрать учёт нуля

 pop  edi
 ret
источник

И

Игорь in Ассемблер
так это сохранение параметров в стек при заходе в функцию, это вроде стандартное правило?
источник

s

s54816 in Ассемблер
Ничего не понял, зачем два add, и у тебя уже был учёт нуля. Обычно strlen наоборот не учитывает ноль.
источник

E

Entusiast in Ассемблер
Я не тестировал, но когда код столкнётся с 0x00 в массиве, jne не прыгнет, и add не выполнится, так что учёт нуля не идёт

add eax, 1
cmp dword[edi], 0x00 ; Ноль?
jne @b ; Да - не прыгать
; ADD не выполнился, учёт нуля не идёт
источник

s

s54816 in Ассемблер
Но у тебя add до сравнения. Для строки из одного нуля оно вернёт 1.
источник

E

Entusiast in Ассемблер
А, верно. Сглупил
источник

D

Den in Ассемблер
Правила придуманы чтобы их нарушать :)) особенно во время оптимизации, вообще работа со стеком же нужна для стандартизации с языками высокого уровня больше а ты мошешь как тебе удобно програмить, стэк путает только лишний раз, потом это лишние обращения в память и лишние уязвимости вот разработчик ngnix-а хвалился что у него надежный сервер потому что он со стеком там практически не работает!
источник

И

Игорь in Ассемблер
я думал суть в том что при заходе в функцию мы освобождаем столько регистров, сколько нам нужно для работы, ну так скажем основные, а выше это просто пример, можно и все сохранить, смотря какая функция
источник

D

Den in Ассемблер
ну если регистров не хватает, стеком конечно удобно пользоваться но пользоваться им на автомате ради самого процесса это уже дело вкуса мне кажется
источник

D

Den in Ассемблер
Вообще в асме процедуры можно использовать и всю работу через регистры делать тем более сейчас их вон сколько а про них забывают и говорят регистров не хватает
источник

D

Den in Ассемблер
Даже кстати в стандарте fastcall это уже поняли что нечего лишний раз стек терзать и быстрее все что нужно через регистры передавать, ну а уж если не хватило, сколько их сейчас около 20 получается только основных
источник

И

Игорь in Ассемблер
20 это в 64битном?
источник

И

Игорь in Ассемблер
я немного не понял)
источник

D

Den in Ассемблер
Ну да там же до r15 где то
источник

И

Игорь in Ассемблер
еще интересно я тут читал статью про процессоры, статья описывает предсказатель ветвлений, вот это интересно. Там описано даже как для каждого типа процессора должен бить организован код, ну по обьему всмысле, что бы код работал быстрее)
источник