Я уже писал когда-то, что 6-й билдер упорно заходил внутрь условия
if (false) {
break;
}
Причем я даже не понял что на это влияло. Добавление одной переменной внутрь этого условия:
if (false) {
int a=1;
break;
}
спасло ситуацию. А сама переменная потом соптимизировалась.
Так что рекомендую поиграться с контекстом. Например сначала сделать
char **temp = table;
а потом уже брать индекс в temp-е.
Синтаксически все верно. Нечего голову себе морочить - пытайся обойти глюки компилятора (уж не думаешь ли ты что компилятор это такая прога, в которой нет глюков :-)) )
Итак, проблема такая:
в Си коде обнаружил следующую строчку:
char* chain_ptr=(char*)table[buff512_r[0]];
Что есть что:
buff512_r- массив из unsigned char. // extern unsigned char buff512_r[512]
table - массив указателей на строки(ASCIIZ) НО по необходимости имеет тип unsigned long. //unsigned long table[256];
chain_ptr - указатель на отдельный символ отдельной строки.
Итак,после долгих моих извращений стало достоверно ясно, что (char*)table[buff512_r[0]] указывает на DS:1E60h ,А!!! chain_ptr мать его так - на DS:2160h!!! *ЛЯ, И ЭТО ПОСЛЕ БАНАЛЬНОГО ПРИСВОЕНИЯ! когда я это увидел - так чуть НЕ абуел (пред глазами пронеслась вся жизнь и вместе с ней все лекции по с/с++). При дизассемблировании стал понят исходный код:
--------
mov bx,[_buff512_r]
mov al,[bx]
mov ah,00
mov cl,2
shl ax,cl
mov bx,ax
mov si,[bx+0984]
---------
что есть что:
si - это младшая часть (1ое слово) указателя chain_ptr ,то есть содержащее им смещение.
код:
mov cl,2
shl ax,cl
как всем известно - умножение ax на 4.
0984 это смещение table.
MOV AL,[BX] - ХРЕН ЗНАЕТ ЧТО ЭТО ТАКОЕ
ИТАК, как все должно было выглядеть:
сначала должен браться индекс (buff512_r[0])
- mov bx,[_buff512_r] -
Затем его умножить на 4, так как unsigned long есть 4 байта.
Потом добавить к получ. рез-ту смещение таблицы..
И получим искомое значение эл-та table[buff512_r[0]](если прочесть word получим соответственно первое слово данного эл-та.. это и будет первым словом в указателе chain_ptr)
Почти Все так и есть.. но не понятна строчка MOV AL,[BX] которая все нафиг портит, потому что этих сра*ых скобок не должно быть вовсе!
Кто что может сказать по этому поводу?
ps DOS программа. компилятор - сабж.
Я уже писал когда-то, что 6-й билдер упорно заходил внутрь условия
if (false) {
break;
}
Причем я даже не понял что на это влияло. Добавление одной переменной внутрь этого условия:
if (false) {
int a=1;
break;
}
спасло ситуацию. А сама переменная потом соптимизировалась.
Так что рекомендую поиграться с контекстом. Например сначала сделать
char **temp = table;
а потом уже брать индекс в temp-е.
Синтаксически все верно. Нечего голову себе морочить - пытайся обойти глюки компилятора (уж не думаешь ли ты что компилятор это такая прога, в которой нет глюков :-)) )
[C++] В защиту Борланда11.10.03 12:08 Автор: :-) <:-)> Статус: Elderman
Но в данном случае виноват не компилятор... buff512_r был объявлен не как массив, а как указатель:
extern unsigned char *buff512_r;
а нужно было так:
extern unsigned char buff512_r[];
Вот и генерился код для разыменования этого указателя:
mov bx,[_buff512_r]
mov al,[bx]
[C++] Вообще-то...11.10.03 15:19 Автор: amirul <Serge> Статус: The Elderman
> Но в данном случае виноват не компилятор... buff512_r был > объявлен не как массив, а как указатель: > extern unsigned char *buff512_r; > а нужно было так: > extern unsigned char buff512_r[]; Там в тексте указано буквально следующее:
buff512_r- массив из unsigned char. // extern unsigned char buff512_r[512]
table - массив указателей на строки(ASCIIZ) НО по необходимости имеет тип unsigned long. //unsigned long table[256];
То бишь оба массива объявлены как действительно массивы. А операция приведения типа вообще одна из самых низкоприоритетных (по крайней мере значительно ниже операции индексировани), так что сначала должен взяться индекс, а потом у взятого значения приводиться тип.
> Вот и генерился код для разыменования этого указателя: > mov bx,[_buff512_r] > mov al,[bx] Хотя даже если бы это был указатель. Индексирование указателя совершенно аналогично индексированию массива. Кроме того, при передаче массива в функцию (даже если указаны константные размерности), он всегда передается как указатель. И тем не менее продолжает работать.
Может в данном случае нам и не сказали всю правду и компилятор действительно не виноват (хотя я сомневаюсь). Но я борландом уже зарекся пользоваться: у меня и моих знакомых было довольно много глюков, которые они вылавливали вылавливали, пока не поняли, что глючит не прога, а компилер. Я ничего не имею против борланда, хотя бы потому, что их продукты стоят $60, а MSVC - $1500. Но писать все равно не хочу.
> Там в тексте указано буквально следующее: [...поскипано]
Все так... Просто мы с автором корневого поста вчера оперативно решили этот вопрос по Аське - ошибка была именно в этом.
http://www.bugtraq.ru/cgi-bin/forum.mcgi?type=sb&b=2&m=89987
> > Вот и генерился код для разыменования этого указателя: > > mov bx,[_buff512_r] > > mov al,[bx] > Хотя даже если бы это был указатель. Индексирование > указателя совершенно аналогично индексированию массива.
Да, с точки зрения языка С индексирование указателя совершенно аналогично индексированию массива. Но я говорю о том, что в обоих случаях генерится совершенно различный код. Мне всегда не нравилось в языке С то, что взглянув на конструкцию вида char c = *buff512_r; и не зная, как объявлен buff512_r (как массив или указатель), нельзя точно сказать, что происходит в терминах Ассемблера. Потому что возможны варианты:
1) если buff512_r - массив типа char, то генерится ОДНО обращение к памяти:
mov al,byte ptr [buff512_r] ; берем один байт по смещению [buff512_r]
2) если buff512_r - указатель, то генерятся ДВА обращения к памяти:
mov bx,[buff512_r] ; берем значение указателя по смещению [buff512_r]
mov al,[bx] ; берем 1 байт по этому указателю
[C++] borland C++ 3.1.Оператор присвоения не работает???10.10.03 21:32 Автор: Cyril <sc> Статус: Member
> привет, давай в аське это обсудим..так легче.... а > результат бесед обязуюсь запостить > стучись : 126092913 я сейчас на работе и уже ухожу, буду только в понедельник, если проблема не решиться то постучусь
> > привет, давай в аське это обсудим..так легче.... а > > результат бесед обязуюсь запостить > > стучись : 126092913 > я сейчас на работе и уже ухожу, буду только в понедельник, > если проблема не решиться то постучусь
ладно.. если быстренько:
в общем мои все претензии к mov al,[bx]
имхо там не должно быть скобок..так как мы берем значение buff512_r[0] еще в строчке mov bx,[_buff512_r] и ЕГО(bx) должны умножны умножать на 4.
> > > привет, давай в аське это обсудим..так легче.... > а > > > результат бесед обязуюсь запостить > > > стучись : 126092913 > > я сейчас на работе и уже ухожу, буду только в > понедельник, > > если проблема не решиться то постучусь > > ладно.. если быстренько: > в общем мои все претензии к mov al,[bx] > имхо там не должно быть скобок..так как мы берем значение > buff512_r[0] еще в строчке mov bx,[_buff512_r] и ЕГО(bx) > должны умножны умножать на 4. > > почему же там стоят скобки???
насчет [bx] вопрос отпадает ...это моя ошибка ... я забыл что buff у меня указатель ((( но факт что присваиваются разные значения остается
А насчет far ptr11.10.03 17:44 Автор: amirul <Serge> Статус: The Elderman
> насчет [bx] вопрос отпадает ...это моя ошибка ... я забыл > что buff у меня указатель ((( но факт что присваиваются > разные значения остается Указатель в DOS-е - это по умолчанию near ptr, а ты ему присваиваешь unsigned long. Непонятно как он это делает
Все зависит от выбранной модели памяти13.10.03 13:10 Автор: Cyril <sc> Статус: Member