Изменение констант в процессе работы., мои наблюдения |
1. Заголовок темы должен быть информативным. В противном случае тема удаляется ...
2. Все тексты программ должны помещаться в теги [code=pas] ... [/code].
3. Прежде чем задавать вопрос, см. "FAQ", если там не нашли ответа, воспользуйтесь ПОИСКОМ, возможно такую задачу уже решали!
4. Не предлагайте свои решения на других языках, кроме Паскаля (исключение - только с согласия модератора).
5. НЕ используйте форум для личного общения, все что не относится к обсуждению темы - на PM!
6. Одна тема - один вопрос (задача)
7. Проверяйте программы перед тем, как разместить их на форуме!!!
8. Спрашивайте и отвечайте четко и по существу!!!
Изменение констант в процессе работы., мои наблюдения |
Altair |
4.11.2004 21:51
Сообщение
#1
|
Ищущий истину Группа: Модераторы Сообщений: 4 824 Пол: Мужской Реальное имя: Олег Репутация: 45 |
Код Uses CRT; Const n=2; D:word=12; var a:array[1..n] of integer; b:word absolute n:2; i:word; c:word absolute d; begin ClrScr; readln(b); for i:=1 to b do a[i]:=random(100); for i:=1 to b do write(a[i],' '); writeln; writeln('c='); readln(c); writeln(d); end. Значение константы, используемой для индексации можно безболезненно менять в меньшую сторону. Значение свободной константы можно изменять свободно. Почему значение констант индексирования нельзя менять в большую сторону при сохранении размера переменной в памяти? ответ: массив или строка увеличится, автоматически новая облать памяти попытается обнулиться, а там могут быть данные чужие, и получаем RUN-TIME ERROR. Если есть подобные примеры работы с директивой absolute, кидайте сюда, может получиться интересная статья в итоге... ЗЫ: Странно, зачем вообще константы в Паскале .... :D -------------------- Помогая друг другу, мы справимся с любыми трудностями!
"Не опускать крылья!" (С) |
xds |
5.11.2004 3:35
Сообщение
#2
|
N337 Группа: Пользователи Сообщений: 737 Пол: Мужской Репутация: 26 |
Не понятна суть проблемы/недовольства.
Код const n = 1; - константа в классическом понимании: при компиляции все вхождения идентификатора n будут заменены на 2. Отсюда Код var d: Word absolute n:2 эквивалентно Код var d: Word absolute 2:2; Т. е. d располагается по адресу $0002:$0002 (физ. адрес $00022, в области $00000..$00400 (физ. адреса) расположена таблица векторов прерываний) и хранит сегментную часть вектора int 8. Недостаточно обдуманное изменение её значения приведет к плачевным последствиям (int 8 = IRQ0 - прерывание системного таймера). Код const d: Word = 12 - "типизированная константа" (typed constant, термин от Borland): Цитата Typed constant declarations are used to declare initialized variables. К слову, Delphi допускает более "корректный" синтаксис: Код var d: Word = 12; -------------------- The idiots are winning.
|
Altair |
5.11.2004 7:02
Сообщение
#3
|
Ищущий истину Группа: Модераторы Сообщений: 4 824 Пол: Мужской Реальное имя: Олег Репутация: 45 |
Цитата Не понятна суть проблемы/недовольства. Проблеммы нет. Вопрос в другом - зачем надо было вводить константы (т.е. постоянные), если их так просто обойти? Зачем вводить огланичение, и сразу вводить способ его обхода? Тем более в теме сказанно что проблеммы нет: Цитата мои наблюдения -------------------- Помогая друг другу, мы справимся с любыми трудностями!
"Не опускать крылья!" (С) |
xds |
5.11.2004 7:27
Сообщение
#4
|
N337 Группа: Пользователи Сообщений: 737 Пол: Мужской Репутация: 26 |
Что касается "типизированных констант", то теперь трудно судить, чем руководствовались разработчики Borland, когда решили в BP инициализированные переменные определять через ключевое слово const.
Польза "настоящих" ("нетипизированных") констант очевидна - под них не выделяется место в сегменте данных, и компилятор может использовать в генерируемом коде инструкции с непосредственной адресацией. К тому же, этот тип констант изначально присутствовал в Паскале как простейшее макросредство. -------------------- The idiots are winning.
|
xds |
5.11.2004 7:39
Сообщение
#5
|
N337 Группа: Пользователи Сообщений: 737 Пол: Мужской Репутация: 26 |
Цитата(Oleg_Z @ 5.11.04 7:02) Вопрос в другом - зачем надо было вводить константы (т.е. постоянные), если их так просто обойти? "Нетипизированную" константу нельзя изменять на этапе выполнения по очевидной причине: она не присутствует в сгенерированном компилятором коде как единственный объект. Из моих наблюдений: в некоторых реализациях BP 7.0 Код ... const a = -0; b = a * -1; ... или даже Код ... Writeln(-2 * Integer(-0)) ... вызывает ошибку компиляции 108: "Overflow in arithmetic operation". Сообщение отредактировано: xds - 5.11.2004 7:48 -------------------- The idiots are winning.
|
Altair |
5.11.2004 13:16
Сообщение
#6
|
Ищущий истину Группа: Модераторы Сообщений: 4 824 Пол: Мужской Реальное имя: Олег Репутация: 45 |
xds, ты глубоко ошибаешся, посмотри - ка код внимательно, я изменяю нетипизированную константу!!!
-------------------- Помогая друг другу, мы справимся с любыми трудностями!
"Не опускать крылья!" (С) |
xds |
5.11.2004 17:56
Сообщение
#7
|
N337 Группа: Пользователи Сообщений: 737 Пол: Мужской Репутация: 26 |
Ах, да где же? Не вижу - ткни меня носом...
Сообщение отредактировано: xds - 5.11.2004 18:08 -------------------- The idiots are winning.
|
GoodWind |
5.11.2004 19:48
Сообщение
#8
|
Автооответчик Группа: Модераторы Сообщений: 1 188 Пол: Мужской Реальное имя: Александр Репутация: 16 |
Цитата Не вижу и я ,кстати, тоже ... :p2: -------------------- Неадекватная чушь может быть адекватным ответом на неадекватный вопрос. Понятно или разжевать?
|
Altair |
6.11.2004 6:54
Сообщение
#9
|
Ищущий истину Группа: Модераторы Сообщений: 4 824 Пол: Мужской Реальное имя: Олег Репутация: 45 |
Код Const n=2; { это константане имеющая типа - нетипизированная } {...} var b:word absolute n:2; { а вот переменная B} {...} begin readln(b); {Изменяем B, но еще и n автоматом} {...} end. -------------------- Помогая друг другу, мы справимся с любыми трудностями!
"Не опускать крылья!" (С) |
Флогримм |
6.11.2004 7:30
Сообщение
#10
|
Бывалый Группа: Пользователи Сообщений: 253 Пол: Мужской Репутация: 4 |
а для чего нужна деректива absolute?
-------------------- Я не буду жить с этой злобой внутри / Я не буду частью смертельной цепи / Я не буду потребителем твоих идей / Я не буду никогда убивать зверей (Unconform)
|
Dark |
6.11.2004 11:01
Сообщение
#11
|
Знаток Группа: Пользователи Сообщений: 408 Пол: Мужской Репутация: 3 |
При помощи прямого доступа к памяти можно обойти абсолютно все, даже в винде, а то не было бы например такой вещи как утилит для игрушек, которые В ПАМЯТИ изменяют значения, РАЗ - и у тебя вместо 20 войнов 200, ДВА и у тебя вместо 1 монеты 50000
А так, никто просто и не собирался предусматривать такой доступ =) а зачем? константа - это только для программиста! это сигнальная система компилятора!!! ну надо тебе - обманывай... но ради чего? -------------------- - Где я?
- Во тьме. - В какой тьме? - Во тьме твоего мозга. |
GoodWind |
6.11.2004 12:59
Сообщение
#12
|
Автооответчик Группа: Модераторы Сообщений: 1 188 Пол: Мужской Реальное имя: Александр Репутация: 16 |
Oleg_Z, понял...
Флогримм, директива absolute нужна для задания адреса переменной в памяти... например: Код var Grscr: array [1..320,1..200] of byte absolute $a000:000; теперь все, что будет писаться в этот массив будет писаться в видеопамять... (в режиме 13h видеопамять начинается с $a000) -------------------- Неадекватная чушь может быть адекватным ответом на неадекватный вопрос. Понятно или разжевать?
|
Altair |
6.11.2004 16:57
Сообщение
#13
|
Ищущий истину Группа: Модераторы Сообщений: 4 824 Пол: Мужской Реальное имя: Олег Репутация: 45 |
Цитата но ради чего? согласен, с памятью шутки плохи просто любопытсво ... -------------------- Помогая друг другу, мы справимся с любыми трудностями!
"Не опускать крылья!" (С) |
xds |
7.11.2004 2:27
Сообщение
#14
|
N337 Группа: Пользователи Сообщений: 737 Пол: Мужской Репутация: 26 |
Конструкция absolute имеет две синтаксических формы:
1. Код var <идентификатор>: <тип> absolute <переменная>; 2. Код var <идентификатор>: <тип> absolute <сегмент>:<смещение>; В первом виде она используется для размещения переменной с именем <идентификатор> типа <тип> по тому же адресу, что и <переменная>. Пример: Код var a: Integer; c: Byte absolute a; Переменная c размещается по тому жу адресу, что и a, т.е. представляет собой младший байт а. Следует отметить, что по absolute место в сегменте данных не выделяется, и следующий код является ошибочным: Код var c: Byte; a: LongInt absolute c; d: Integer; a выходит за границы участка памяти, выделенного под c, и при записи в a мы в лучшем случае испортим значение d. Во втором виде, она используется для размещения переменной с именем <идентификатор> типа <тип> в памяти по абсолютному (сегментному) адресу <сегмент>:<смещение> (её физический адрес будет равен <сегмент> * 16 + <смещение>, где "*" - операция арифметического умножения, "+" - операция арифметического сложения, а "16" - число в десятичной форме записи :P :D). GoodWind уже привел пример такого случая. -------------------- The idiots are winning.
|
xds |
7.11.2004 2:38
Сообщение
#15
|
N337 Группа: Пользователи Сообщений: 737 Пол: Мужской Репутация: 26 |
Цитата(Oleg_Z @ 6.11.04 6:54) Код Const n=2; { это константане имеющая типа - нетипизированная } {...} var b:word absolute n:2; { а вот переменная B} {...} begin readln(b); {Изменяем B, но еще и n автоматом} {...} end. Ух, Олежка, вцени: Код program Code; uses Dos; const n = 2; var x: Word absolute n:2; p: Pointer; begin Writeln(x); GetIntVec(8, p); Writeln(LongInt(p) shr 16); end. :D -------------------- The idiots are winning.
|
Флогримм |
7.11.2004 6:11
Сообщение
#16
|
Бывалый Группа: Пользователи Сообщений: 253 Пол: Мужской Репутация: 4 |
Я еще с памятью никогда не работал. Что такое сегмент и смещение и зачем они нужны? Зачем нужен прямой доступ к памяти? Что подразумевается под памятью(оперативная что ли?)?
xds var Код a: Integer; c: Byte absolute a; т.е. если мы переменной а присвоим какое-то значение, оно автоматически присвоется с? -------------------- Я не буду жить с этой злобой внутри / Я не буду частью смертельной цепи / Я не буду потребителем твоих идей / Я не буду никогда убивать зверей (Unconform)
|
Altair |
7.11.2004 9:00
Сообщение
#17
|
Ищущий истину Группа: Модераторы Сообщений: 4 824 Пол: Мужской Реальное имя: Олег Репутация: 45 |
В последнем примере, две переменные расположенны по одному адресу, но размер разные, и переменная с является верхним разрядом переменной а.
Цитата Ух, Олежка, вцени: Вценил! Круто! Цитата Что подразумевается под памятью( Конечно оперативка... ведь не сказанно что внешняя память... а какая по твоему еще есть? Ну ПЗУ мы не рассматриваем :D :P Цитата Зачем нужен прямой доступ к памяти? Для большинства прикладных программ, обходится без них... а вот для системных утилит иногда надо обратится к памяти напрямую... Цитата Что такое сегмент и смещение и зачем они нужны? Сегментом и смещением характеризуется адрес в ОП. ИМХО ответ на это есть в очень подробном виде на форум "Ассемблер" (где Dark модер) тебе туда... т.к. в основном всю эту бяку используют там... здесь это ненужно... -------------------- Помогая друг другу, мы справимся с любыми трудностями!
"Не опускать крылья!" (С) |
xds |
7.11.2004 9:14
Сообщение
#18
|
N337 Группа: Пользователи Сообщений: 737 Пол: Мужской Репутация: 26 |
Под "памятью" подразумеваются адресное пространство ЦП, в котором располагаются ОЗУ (оперативная память), основное ПЗУ (обычно содержит BIOS), видеобуфер и т. п.
Сегментные адреса были введены в семействе x86 по той простой причине, что первые модели (i8086/88, i80186, i80286) были 16-разрядными. Перед разработчиками Intel стояла проблема: с помощью 16-разрядного слова можно адресовать только 64 кб, что шло в разрез с уже достаточно высоким потенциалом возможностей системы команд x86. Поступили следующим образом: шину адреса сделали 20-разрядной, что позволило увеличить адресное пространство до 1 Мб. Поскольку процессор мог оперировать только словами длиной 8 и 16 бит, то ввели концепцию сегментных адресов. Сегментный адрес имеет длину 32 бита и состоит из 2 16-разрядных слов - сегмента и смещения. Сегментный адрес автоматически преобразуется процессором в физический следующим образом (повторюсь): <физический_адрес> := <сегмент> * 16 + <смещение>. Т. о. одной физической ячейке памяти соответствует 4096 различных сегментных адресов. Все указанное выше справедливо для любой модели x86, работающей в режиме real x86. -------------------- The idiots are winning.
|
xds |
7.11.2004 9:21
Сообщение
#19
|
N337 Группа: Пользователи Сообщений: 737 Пол: Мужской Репутация: 26 |
Цитата переменная с является верхним разрядом переменной а. Младшим байтом! (в Intel принят порядок little-endian) Цитата Вценил! Круто! Что круто-то? -------------------- The idiots are winning.
|
Altair |
7.11.2004 9:33
Сообщение
#20
|
Ищущий истину Группа: Модераторы Сообщений: 4 824 Пол: Мужской Реальное имя: Олег Репутация: 45 |
Цитата Что круто-то? А ты про что? Цитата Младшим байтом! (в Intel принят порядок little-endian) Да, точно. Ошибся, действительно, они распологаются задом наперед ... Цитата little-endian reverse-byte sequence. Младший байт в ячейке с меньшим адресом, а старший в ячейке с большим адресом. -------------------- Помогая друг другу, мы справимся с любыми трудностями!
"Не опускать крылья!" (С) |
Текстовая версия | 29.04.2024 20:43 |