vak: (Default)
[personal profile] vak
Рыться в древних исходниках - увлекательное занятие. На днях исправил забавную ошибку в /bin/sh (из Unix версии 2.11BSD). Свободная память хранится в виде односвязного списка, проход по которому включал следующий фрагмент:
struct blk {
    struct blk *word;
} *p, *q;

#define busy(x) ((int)(x)->word & 1)

p = ...;
while (! busy (q = p->word)) {
    p->word = q->word;
}
Прелесть в том, что конец списка может быть нулём. В цикле - хотя это не очевидно из текста - по нулевому указателю будет извлечено слово и проверен младший разряд. Если там окажется единица - нам повезло, иначе система зацикливается. На PDP-11 по нулевому адресу располагалась инструкция SETD с кодом 0170011, и шелл прекрасно работал. На симуляторе MIPS32 тоже работал первое время, пока конфигурация не изменилась.

Date: 2011-07-27 07:31 (UTC)
From: [identity profile] http://users.livejournal.com/_slw/
http://pages.cpsc.ucalgary.ca/~dsb/PDP11/DoubOp.html

mov @X(R0), @R1

какой-такой SETD? нет у PDP-11 такой инструкции.

вообще, там по идее должен быть JMP или EMT/TRAP

Date: 2011-07-27 07:42 (UTC)
From: [identity profile] dmarck.livejournal.com
Именно это, кажется, и называется божьим попыщением ;-P

Date: 2011-07-27 07:56 (UTC)
From: [identity profile] http://users.livejournal.com/_slw/
да и битов в числе 0170011 как-то многовато для pdp-11

Date: 2011-07-27 08:18 (UTC)
From: [identity profile] http://users.livejournal.com/_slw/
я, простите, не понял, а куда они вектора прерываний дели?
вот так вот по простому поверх всяких TRAP TO 4 и прочих?!

Date: 2011-07-27 08:32 (UTC)
From: [identity profile] crimcat.livejournal.com
Может, так и было изначально задумано? А потом - забыли:)

Date: 2011-07-27 08:41 (UTC)
From: [identity profile] dmarck.livejournal.com
3*6=18, в старшей цифре используется один. где проблемы?

Date: 2011-07-27 08:45 (UTC)
From: [identity profile] http://users.livejournal.com/_slw/
два байта по 8 --- это 16. проблема!

Date: 2011-07-27 09:39 (UTC)
From: [identity profile] ufm.livejournal.com
0170011 == 0xF009

В чем проблема-то?

Date: 2011-07-27 09:44 (UTC)
From: [identity profile] http://users.livejournal.com/_slw/
0 -- значащий.

Date: 2011-07-27 09:48 (UTC)
From: [identity profile] ufm.livejournal.com
Да ну? Всю жисть так восьмеричное записывалось - 0xxxyyy

Date: 2011-07-27 09:53 (UTC)
From: [identity profile] http://users.livejournal.com/_slw/
никогда оно так не записывалось при разговоре о системе комманд pdp-11.
так же как при разговоре о системе команд z80 никто не писал 0xFF.

Date: 2011-07-27 09:54 (UTC)
From: [identity profile] ufm.livejournal.com
А 0170011 - это разве не к FP11 отношение имеет?

P.S. ничего уже не помню. Единственный опкод который намертво вошел в память - 14747 - уж больно он красивый результат даёт.

Date: 2011-07-27 10:09 (UTC)
From: [identity profile] mandrykin.livejournal.com
0170011(8) = 1111 0000 0000 1001(2)
Вроде нормально всё. Вас старший незначащий ноль смутил?

printf("%d %d %d\n", 10, 010, 0x10 );

:)

Date: 2011-07-27 10:13 (UTC)
From: [identity profile] ufm.livejournal.com
В терминах Це - всегда. В данном случае у меня щелкнули два переключателя: PDP11 - значит восьмеричное. Цэ - значит начинается с 0.

Date: 2011-07-27 12:42 (UTC)
From: [identity profile] kashnikov.livejournal.com
SETD есть у сопроцессора FP11.

Date: 2011-07-27 12:54 (UTC)
From: [identity profile] dvv.livejournal.com
Натурально имеет. Юзерный код в BSD (и не только) на PDP11 по умолчанию работал в double mode.

Date: 2011-07-27 13:16 (UTC)
From: [identity profile] paracloud.livejournal.com
Эх, а я до сих пор студентов мучаю pdp-ишной системой команд - с целью написания простого симулятора.

И помню сказочное:

JSR PC,(PC) ; DO WHAT FOLLOWS TWICE
JSR PC,(PC) ; NO, I MEAN 4 TIMES
...

где то в недрах ODT.
From: [identity profile] che2i0s.livejournal.com
Я перепахал километры китайского кода - кстати платили раза в два или три больше, чем авторам.
Если по какой-то причине Purify, Valgrind и тд ошибки на регрессном тестировании не обнаруживают (а это случается, когда fuck up происходит в распределенной области памяти), то struct blk *word заменяется по
#ifdef CHECK_MODE
safe_vector word[];
#endif
который уже такие ошибки array out of bounds отстреливает.
Но в целом - shame! Делает код дороже.