Если заранее известно, что в данной точке кода EAX == 0, и мне нужна единица в ECX, что будет эффективнее: Так: xor ecx,ecx dec ecx Или: lea ecx,[eax-1] Длина - 3 байта в любом случае, но в первом инструкций две, причем вторая зависит от резутатов первой. Это имеет значение? Или же в любом случае 1 такт? Просто mov ecx,1 - 5 байт.
А нужна скорость или размер? Если скорость - mov ecx,1 ,а если размер - решай сам. (только не dec, а inc)
Во-первых, есть еще один 3-х байтный вариант or ecx,-1 ;-1 = sign-extended byte Во-вторых, судить по одной-двум инструкциям, что в итоге будет эффективней не вполне корректно, т.к. проц работает с потоком команд и может выполнять за такт несколько операций, изменяя их порядок на глубине до 8-16 и более. Не считая mov, все варианты имеют зависимости от предыдущего значения (eax или ecx), но для lea и or эта зависимость определяется неизвестными предыдущими командами, а в варианте с xor она присутсвует явно. Причем нужно иметь в виду, что в современных процессорах команды xor\sub регистра с самим собой имеют особый смысл операций очистки регистра и считаются независящими от его предыдущего значения и поэтому (также как и NOP) могут выполняться вне очереди в любой подходящий момент (в т.ч параллельно с другими операциями). Поэтому в отрыве от окружающего кода говорить о том, что в итоге будет быстрее - не корректно. Если для тебя один такт и пару байт критичны, то нужно рассматривать и оптимизировать весь кусок, если же нет - то используй любой вариант по вкусу PS: Кстати inc\dec не очень хорошие инструкции, т.к. они вносят зависимость по флагу CF, и к тому же в x86-64, за которыми как ни крути - будущее, однобайтные inc\dec "ликвидированы" и оставлены только двухбайтные
ADim Вот в этом фрагментике программы, скомпилированной Мелкософтовским компилятором, информация о том, что eax=0, не используется при задании ecx=-1 Так что воспользуйся советом leo.
Great, asmfan Я ошибся в описании! Нужна -1 ("минус единица"). Соответственно, mov ecx, 0ffffffffh ; -1 Mikl__ К сожалению, при этом теряется 0 в eax, придется добавить xor eax,eax. + 2 байта. leo Ваш вариан or ecx,-1 со знаковым расширением очень удачен, спасибо. После операций очистки регистров, т.е. установки регистров в определенное значение 0, зависимость сохраняется? Т.е. после XOR ECX,ECX до следующего изменения ECX не допускается внеочередного исполнения команд с участием ECX (без его изменения)? Насколько вероятно в процессорах, начиная с P6, не одновременное исполнение xor ecx,ecx / dec ecx ??? А интересовало меня, можно ли в три байта уложиться в один такт, если эти три байта - не одна инструкция, точнее, насколько вероятно, что поток команд так попадет в устройства процессора, что исполнение их займет один такт. Предыдущих команд, наподобие fsin, полностью маскирующих время след. инструкций нет или, еще лучше, может не быть. -- -- Не могли бы вкратце пояснить, будет ли разница в обнулении регистра (общего) SUB или XOR?
ADim Какие то запутанные вопросы задаешь 1) Разницы в использовании xor или sub для обнуления нет (если быть точным, то только в P4 м.б. тонкая разница, т.к. в P4 логический блок один, а add\sub - два) 2) Операции xor и dec не могут выполниться одновременно, т.к. dec зависит от xor, поэтому за один такт они вместе выполниться никак не могут 3) Но xor, будучи независимой операцией, может выполниться раньше, параллельно с другими операциями (в том числе и одновременно и даже раньше предыдущих операций, изменяющих этот же регистр !). Подобие fsin тут никчему, т.к. во-первых, современные процы могут выполнять одновременно 2-3 целочисленных операции плюс 1-3 операции вычисления адреса для mov, во-вторых, во время исполнения операциий mov c памятью, mul\imul и т.п. может быть выполнено множество других простых операций. Примеры Код (Text): ;Код 1А add ecx,4 ;1й такт mov [ebx],ecx ;2й такт or ecx,-1 ;2й такт, т.к. зависит от add ecx,4 ;Код 1Б add ecx,4 ;1й такт mov [ebx],ecx ;2й такт xor ecx,ecx ;1й такт, если попадает в одну тройку с add ecx dec ecx ;2й такт, т.к. зависит от xor ;Код 2А add ecx,[ebx] ;1-4й такты (3 на загрузку, 1 на add) mul ecx ;5-?й такты (3\4-5\10\14 в завис.от проца) or ecx,-1 ;5й такт, т.к. зависит от add ecx,[ebx] ;Код 2Б add ecx,[ebx] ;1-4й такты mul ecx ;5-?й такты xor ecx,ecx ;1й или 2й такт, т.к. не зависит от ecx dec ecx ;2й или 3й такт Вывод: нельзя рассматривать две инструкции в отрыве от предыдущего кода - в зависимости от откружения м.б. либо один вариант быстрее, либо другой, либо без разницы PS: Чтобы не было лишних вопросов: в примере 2Б xor может выполниться раньше изменения ecx и mul за счет переименования регистров в процессоре (операциям add и mul назначается внутренний регистр ecx==R, а операциям xor и dec ecx==R[i+1])
ADim команда MOV не имеет знакового расширения в отличее от логических команд (OR,XOR,AND), но если в одном из регистров у вас 0 (я использую EBX=0), то Код (Text): B80D000000 mov eax,0Dh (5 байт) 8D430D lea eax,[ebx+0Dh](3 байта) B8FFFFFFFF mov eax,-1(5 байт) 8D43FF lea eax,[ebx-1](3 байта) а про быстродействие пусть leo скажет
Mikl__ А у ADim то же самое, только EAX=0 А насчет быстродействия - на атлонах lea r,[r+i] выполняется 2 такта, на остальных камнях 1 такт. Если регистр сброшен "давно и надолго", то зависимости можно не учитывать
Большое спасибо, многое стало ясно Про разницу sub/xor спрашивал, т.к. в руководстве по оптимизации для K8 указана XOR, а для P4 - XOR или SUB. Ремарок там нет.