Во время отладки проблемы с программой, сбой на искаженном указателе, который был разыменован, я запустил lldb
и выполнил разборку функции сбоя. В то время как просматривал полученный код, я заметил этот странный выглядящий выбор инструкций:Почему выход ассемблера Клана условно переходит к безусловному прыжку?
0x100002b06 <+86>: cmpl $0x0, %eax 0x100002b09 <+89>: je 0x100002b14 0x100002b0f <+95>: jmp 0x10000330e 0x100002b14 <+100>: jmp 0x100002c1d
Я бы ожидать код выглядеть как это вместо:
0x100002b06 <+86>: cmpl $0x0, %eax 0x100002b09 <+89>: je 0x100002c1d 0x100002b0f <+95>: jmp 0x10000330e
I Любопытно, почему Кланг сделал этот выбор. Это какая-то оптимизация прогноза ветвления, поскольку это проверка указателя NULL, которая вряд ли будет соответствовать?
Редактировать:This is the originating C code, В частности, строка с проверкой указателя NULL.
traverse = travdone_head;
while (1) {
if (traverse == NULL) nullptr("grokdir() traverse");
/* Don't re-traverse directories we've already seen */
if (inode == traverse->inode && device == traverse->device) {
Был ли ваш код скомпилирован в режиме отладки? Если это так, это может объяснить, почему код сборки был написан таким образом. –
Он был скомпилирован с '-O0 -g3'. По-прежнему кажется немного странным, что он произвел прыжок в прыжок, но это, вероятно, объяснит это. –
С тех пор как вы добавили тег C: каковы исходные строки, которые привели к этому коду? – usr2564301