Неудачный выбор приоритетов на PDP-11 и его наследие на Си


Источник проблемы


Виновницей оказалась мерзопакостная конструкция типа "*p[a]++", которая вопреки логике увеличивает отнюдь _не_ содержимое ячейки, на которую указывает "*(p+a)", а значение самого указателя p, то есть транслируется в следующий ассемблерный код:

mov    eax, dword ptr

[p]   ; прочитать адрес переменной p

mov    ecx, dword ptr

[eax] ; прочитать значение указателя, на который указывает p

add    ecx, 1               ; увеличить содержимое указателя на кот. указывает p

mov    edx, dword ptr

[p]   ; прочитать адрес переменной p

mov    dword ptr [edx], ecx ; занести в переменную p ее обновленное значение

Листинг 1 ассемблерный код в который транслируется *p[a]++

Специально написанный для этого дела демонстрационный пример (см. листинг 3) в отладчике выглядел так:

 

Рисунок 1 откомпилированная конструкция *p[a]++ под лупой отладчика

В то время, как _ожидаемый_ вариант трансляции должен был выглядеть так:

 

mov    eax, dword ptr

[p]   ; прочитать адрес переменной p

mov    ecx, dword ptr

[eax] ; прочитать значение указателя на который указывает p

mov    dl, byte ptr

[ecx]   ; прочитать значение переменной на которую указывает *p

add    dl, 1                ; увеличить значение переменной на 1

mov    eax, dword ptr

[p]   ; прочитать адрес переменной p

mov    ecx, dword ptr

[eax] ; прочитать значение указателя на который указывает p

mov    byte ptr [ecx], dl   ; занести обновленное значение переменной *p[a]

Листинг 2 ожидаемый вариант трансляции конструкции *p[a]++




- Начало -  - Назад -  - Вперед -