здравствуйте, не могу понять следующий выхлоп:
ex::ex():
movq $0, (%rdi)
movq $0, 992(%rdi)
movq %rdi, %rcx
leaq 8(%rdi), %rdi
xorl %eax, %eax
andq $-8, %rdi
subq %rdi, %rcx
addl $1000, %ecx
shrl $3, %ecx
rep stosq
ret
для кода:
class ex {
public:
ex() :a{0} {}
char a[1000];
};
int main() {
ex a;
}
читал, что rep stosq делает примерно то же, что и цикл, заполняя что-то пока ecx > 0, вот только не могу толком понять что. в подобных вопросах говорят, что вроде edi заполняется значениями из eax... однако полного понимания как достигается обнуление массива в 1000 элементов нету... разъясните по инструкциям что там и зачем, сдвиг на 3 или вот это, например, зачем:
movq $0, (%rdi)
movq $0, 992(%rdi)
обновление: в общем, предыдущий выхлоп был с -fno-inline, без него генерится вот это:
subq $1016, %rsp
movl $125, %ecx
xorl %eax, %eax
movq %rsp, %rdi
rep stosq
вопрос тот же: что за треш с rep stosq?
Сдвиг на 3 нужен потому, что компилятор желает использовать инструкцию rep stosq
, которая заполняет память не побайтно, а по 8-байтным словам. Поэтому количество итераций, которое надо сделать инструкции rep stosq
равно размеру буфера, деленному на 8. Это и есть сдвиг вправо на 3.
То есть при подходе "в лоб" надо просто сделать 125 итераций rep stosq
.
Однако для того, чтобы rep stosq
работала эффективнее, необходимо, чтобы ее целевой адрес был выровнен на границу 8 байт. Ваш буфер a
не гарантированно выровнен на границу 8 байт. Поэтому компилятор делает следующее: первое и последнее 8-байтное слово вашего буфера обнуляются индивидуально. Именно это делают инструкции
movq $0, (%rdi)
movq $0, 992(%rdi)
А далее компилятор вычисляет выровненный на границу 8 байт адрес, с которого надо начать обнуление оставшейся "серединки" вашего буфера
leaq 8(%rdi), %rdi
andq $-8, %rdi
а также вычисляет, сколько надо сделать итераций rep stosq
, чтобы обнулить эту "серединку". Для вычисления количества итераций мы вычитаем из ecx
(который в этот момент содержит точное начало буфера), значение выровненного начала
subq %rdi, %rcx
Если произошло фактическое выравнивание, то значение rcx
станет отрицательным (более того, даже при выровненном буфере rdi
здесь содержит адрес второго слова, т.е. значение rcx
в любом случае будет отрицательным). Затем
addl $1000, %ecx
shrl $3, %ecx
вычислит требуемое количество итераций, которое в общем случае получится меньше, чем 125 (т.е. 124).
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Есть массив unsigned __int64В него необходимо дописать 2 бита
Рабочее приложение сотрудника (клиент) транслирует веб-камеруНужно определять не заклеена ли камера и не заблокирована ли она какой-то программой
How to connect Excel to a VS C ++ CLI projectNamely, how to interact with data cells in Excel, how to move from cell to cell, and give please a book on this topic (preferably in Russian)