Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2003.05.08;
Скачать: [xml.tar.bz2];

Вниз

Почему допустимо integer(<адрес в памяти>) ?   Найти похожие ветки 

 
Giemgo   (2003-04-15 15:55) [0]

Не очень силен в битовой логике. Или может даже очень не силен.

Но видел, что люди пишут, допустим, так:

integer(p)+1 когда нужен адрес байта следующего после p
где p - адрес в памяти

Хотя ведь правильней LongWord(p)+1 ?

Так как integer - это знаковое целое. А адрес не может быть отрицательным... и на хранение положительного числа у integer отводится 31 бит, в то время как адрес - это 32-ух битовое положительное число.


 
Anatoly Podgoretsky   (2003-04-15 16:04) [1]

Они расчитывают на такой факт, что в данный момент (для Д2-Д7), из размеры равны. Но для этого есть более подзодящий мезанизм, для PChar поддержана адресная математика.


 
Digitman   (2003-04-15 16:08) [2]

ну и что ?

с т.з. компилятора операция
integer(p)+1
вполне легальна - требуется сложение двух знаковых целых числа

а вот дальше, коль p - это Pointer и требуется после его модификации (любым легальным способом) обратиться к адресу в памяти, значение этого указателя рассматривается не как знаковое, а как беззнаковое целое


 
Fantasist.   (2003-04-15 17:18) [3]


> с т.з. компилятора операция
> integer(p)+1
> вполне легальна - требуется сложение двух знаковых целых
> числа


Положим, у нас есть число (8 байт):

10000011

Допустим, это адрес, а как целое число оно равно -3 (первый бит - знак). При сложении с +1 оно превращается в -2, в битовом виде 10000010, что соответствует адресу предыдущего байта, а не следующего.



 
MBo   (2003-04-15 17:25) [4]

>Fantasist
Ты ошибаешься -
однобайтовое число в дв. виде
-3 11111100
+1
-2 11111110


 
Skier   (2003-04-15 17:26) [5]

Положим, у нас есть число (8 байт):

10000011 - Это что, батенька, 8 байт ?!


 
Skier   (2003-04-15 17:33) [6]

>MBo © (15.04.03 17:25)
Борис, 11111100 - это -4 - (дополнительный код)



 
Fantasist.   (2003-04-15 17:38) [7]


> 10000011 - Это что, батенька, 8 байт


Нет, бит. Думаю, вы и сами это видите.



> Ты ошибаешься -
> однобайтовое число в дв. виде
> -3 11111100
> +1
> -2 11111110


Хорошо. Пусть так - не суть. При преобразовании к адресу все равно результат получается не адрес следующего байта.


 
Anatoly Podgoretsky   (2003-04-15 17:46) [8]

Fantasist. (15.04.03 17:18)
Вам в школу, и по количеству байт и по математическим операция и с каких пор адрес стал знаковым?

-3 11111100 +1
-2 11111101


 
Skier   (2003-04-15 17:48) [9]

>Fantasist.

> Допустим, это адрес, а как целое число оно равно -3 (первый
> бит - знак).

Если это адрес, то он воспринимаеться как беззнаковое число
см. Digitman © (15.04.03 16:08).


 
DiamondShark   (2003-04-15 17:48) [10]

У-уу! Как всё запущено.


знаковое(10) двоичное беззнаковое(10)
-3 11111111111111111111111111111101 4294967293
+1 00000000000000000000000000000001 1
-2 11111111111111111111111111111110 4294967294


Какие ещё вопросы?


 
MBo   (2003-04-15 17:52) [11]

>Skier
да, верно, ведь 11111111b=-1
да и сложил я неправильно ;)


-3 11111101
+1
-2 11111110

если рассматривать как беззнаковые
253+1=254
адрес следующего байта и есть




 
Digitman   (2003-04-15 17:57) [12]


> Fantasist


ну и что из этого следует ?

да, при расширении байта (как ShortInt) до Integer знаковый бит дублируется во все дополняемые слева разряды, и результатом сложения будет знаковый декремент

нет, при расширении байта (как Byte) до Integer знаковый бит все дополняемые слева разряды будут обнулены, и результатом сложения будет знаковый инкремент

это должен контролировать ты как программист ! учитывая факт.тип, которым для компилятора представлен этот самый байт байт !
а в действиях компилятора - все чики-пики будет ! Как ты заказал, так и получил результат)


 
Fantasist.   (2003-04-15 18:44) [13]

Ну вот и отличненько. А в школу, как предлагает Podgoretsky я все-таки не пойду.


> каких пор адрес стал знаковым


А вот вы Анатолий, мало того, что грубовато выражаетесь, так еще и невнимательно читаете - это утверждение я никогда не произносил. Я всего лишь пытался обратить внимание, что сложение знаковых чисел на битовом уровне может быть не всегда совместимым с беззнаковыми(адрес). Если я ошибся - да будет так, не в первой.


 
Giemgo   (2003-04-15 20:47) [14]

Так. Для понимания ваших ответов, которые половина неправильная, даже ответы мастеров, скажите мне такую вещь.

Если мы рассмотрим однобайтовое знаковое.

Его наибольшее значение 01111111 - это понятно.
Наименьшее значение 111111111 - в прямом коде.
Но так как числа в x86 хранятся в дополнительном, то наименьшее число будет 00000001, так как NEG 11111111=00000001

Отсюда вопрос. А как понять, что там за число хранится ? То ли
-127, то ли +1


 
default   (2003-04-15 22:27) [15]

вот ответ проще некуда
Byte(ShortInt(130) + 1) = 131
ShortInt(130) = -126
Byte(-125) = 131 (приведение к Pointer это почти то же что и к LongWord/DWORD/Cardinal)
(то есть адрес трактуется как целое беззнаковое число)
начально значение адреса: 130
конечное значение адреса: 131
вот весь фокус
а если ещё проще говорить то неважно к какому типу ты приводишь адрес
лишь бы его размер соответстовал адресу


 
Anatoly Podgoretsky   (2003-04-15 22:31) [16]

Fantasist. (15.04.03 18:44)
Сложение Integer всегда даст правильный результат, деже если к нему приведен Pointer.
В процессоре нет отдельной команды для сложения со знаком и без, на это одна единстственна команда ADD


 
Anatoly Podgoretsky   (2003-04-15 22:35) [17]

Да, в школу емеется в виду в школу Юрия Зотова, особенно первые три класса, чейчас он ведет четрверный клас. Я не помню точно в каком именно классе он объясняет операция сложени для знаковых и беззнаковых цисел. Толь первый толи второй урок. Так где речь идет про биты.


 
Giemgo   (2003-04-16 00:10) [18]

Ответьте, пожалуйста, на вопрос.

Если мы рассмотрим однобайтовое знаковое.

Его наибольшее значение 01111111 - это понятно.
Наименьшее значение 111111111 - в прямом коде.
Но так как числа в x86 хранятся в дополнительном, то наименьшее число будет 00000001, так как NEG 11111111=00000001

Отсюда вопрос. А как понять, что там за число хранится ? То ли
-127, то ли +1


 
А123   (2003-04-16 00:23) [19]

2 Giemgo (16.04.03 00:10)
11111111 это -127
00000001 это +1
А NEG тут несколько не причем, поскольку 11111111 - это уже дополнительный код.


 
А123   (2003-04-16 00:26) [20]

Пардон ступил.
11111111 - это -1
а -127 это 10000001


 
Anatoly Podgoretsky   (2003-04-16 00:49) [21]

Giemgo (16.04.03 00:10)

Наименьшее значение не 111111111 - а 10000000
NEG 11111111=00000001 -> 00000000!!! или ты про какой NEG говоришь


 
Юрий Зотов   (2003-04-16 08:14) [22]

> Giemgo

Полезные ссылки:

www.sgu.ru/kafedra/teorin/Lekciya_99.htm
www.happytown.ru/prog/data/simple.html
www.i-u.ru/biblio/arhiv/books/noname_uchInform/ec4.asp
stratum.pstu.ac.ru/~leonid/base
user.rol.ru/~voidmain/asm.zip


 
Palladin   (2003-04-16 08:27) [23]

вот ведь развели полемику из-за одного вопроса
"Почему допустимо integer(<адрес в памяти>)?"

а потому что 16 бит, они все время 16 бит, и знака у них нет, это массив бит...
а type casting"у без разницы, лишь бы размер совпадал.

по поводу вопроса

> Giemgo (16.04.03 00:10)


как понять...
как тебе надо так и понимай...
ведь ты же переменную описываешь! byte или shortint... или еще как...


 
Digitman   (2003-04-16 08:41) [24]


> Giemgo


Диапазон представлений целовых чисел со знаком, хранимых байтом
-128 .. +127, а беззнаковых целых - 0..255

Любая операция сложения/вычитания над байтом (как бы он ни интерпретировалось его содержимое - как знаковое или как беззнаковое) даст один и тот же результат - одну и ту же битовую комбинацию в результирующем байте.

Другой вопрос, что арифм.операции (например, ADD или SUB), интерпретирующие байт как знаковое целое, кроме собственно формирования результата устанавливают флаги CF (перенос/заем значащего разряда), OF (арифм.переполнение), SF (знак арифм.результата), ZF (результат равен нулю), PF (паритет результата). Любая последующая инструкция может проанализировать (либо задействовать их непосредственно) эти флаги, если это требуется по алгоритму.

Скажем, результат выполнения инструкций INC BYTE (1) и ADD BYTE,VALUE (2) будет одинаков при любом исходном содержимом операнда BYTE. Но ! Инструкция INC установит флаги ZF, SF, ОF, PF, оставив флаг CF без изменений. Инструкция же ADD установит еще и флаг CF, для того чтобы, например, следом идущая арифм.инструкция могла учесть результат выполнения предыдущей ИМЕННО как результат ЗНАКОВОЙ операции !


 
Giemgo   (2003-04-16 10:45) [25]

Слушайте, я все немного неправильно описал. Я интуитивно понимал, а объяснить не мог. Вот сейчас подумал - расскажу в чем мне кажется проблема то.

Давайте представим, что указатель - это однобайтовое целое (не хочу лишние единички и нули писать). А также integer и LongWord это однобайтовые целые.

Также предположим, что P:=01111111b

Соответственно, если мы хотим узнать номер следующего байта в памяти, делаем так:

P:=Pointer(LongWord(P)+1) правильно ? Получаем 10000000b

Но ! Если мы сделаем с помощью integer:

P:=Pointer(Integer(P)+1) что мы получим ?

Ведь 01111111b это максимальное значение для integer (напомню, что мы договорились, что integer однобайтовое знаковое). И если прибавить еденицу - то будет переполнение ! А не адрес следующего байта. Вот что я хотел сказать. Все сказанное можно отнести и к 32-ух битовым системам. По любому у integer на 1 бит меньше места для хранения числа, чем у LongWord

А теперь догадки, почему, когда используют integer нет ошибок. Да мне кажется потому, что в программах высшие области памяти не используются, особенно в программах типа Hello, World. Соответственно у существующих указателях не то, что старший бит, а вообще старший байт равен нулю. И ошибка не всплывает.


 
Anatoly Podgoretsky   (2003-04-16 10:51) [26]

Мы получим 10000000b
Книги или просто проверка в Дельфи помогут тебе встать на правильную дорго


 
Digitman   (2003-04-16 11:01) [27]


> P:=Pointer(LongWord(P)+1) правильно ? Получаем 10000000b


это не вызывает сомнений


> Но ! Если мы сделаем с помощью integer:
>
> P:=Pointer(Integer(P)+1) что мы получим ?


да тоже самое и получим ! 10000000b ! при чем здесь переполнение-то ? для последующено обращения к ячейке памяти по адресу (результирующему значению переменной-указателя P) = 10000000b никакое предыдущее "арифм.переполнение разрядной сетки" не играет никакой роли ! P^ := XXX - это же не арифм.операция !



 
Palladin   (2003-04-16 11:04) [28]

Pointer(10000000)=128
Integer(10000000)=-128;

заметь одно и тоже, а представление разное...


 
Skier   (2003-04-16 11:07) [29]

>Integer(10000000)=-128;
?!


 
Digitman   (2003-04-16 11:13) [30]


> Skier


Для простоты автор подразумевает, что Integer - это ShortInt (байт)



 
Skier   (2003-04-16 11:15) [31]

>Palladin
Мои извинения, не учёл : "напомню, что мы договорились, что integer однобайтовое знаковое"


 
Giemgo   (2003-04-16 15:05) [32]

последующено обращения к ячейке памяти по адресу (результирующему значению переменной-указателя P) = 10000000b никакое предыдущее "арифм.переполнение разрядной сетки" не играет никакой роли

Это понятно. Ну смотрите. Давайте разберем по шагам - скажите где я ошибся:

Integer(P)+1

Сначала P приводится к integer. В нашем случае это +128
И вот мне интересно в каком контексте происходит сложение. Если в контексте integer, то так получается +129, то оно в integer "не влезет". Я помню, что когда integer переходит свои границы, то в результате получается фиг знает что.
Тем более с точки зрения integer значение 10000000b это некорректный результат. Так почему он складывается нормально? Ведь если написать

i:=128
i:=i+1

- то ничего не получится


 
Digitman   (2003-04-16 15:19) [33]

10000000b
+
00000001b
-----------
10000001b

вот так физически (и никак по иному !!!) происходит сложение двух операндов в ходе исполнения процессором маш.инструкции . Хоть "со знаком" операнды, хоть "без знака" )

Это понятно ? Не вызывает вопросов ?



 
erikIvanov   (2003-04-16 15:20) [34]

Крыша у вас поешела, делать нечего биты складывать?


 
Anatoly Podgoretsky   (2003-04-16 15:25) [35]

Giemgo (16.04.03 15:05)
Число +128, как знаковое, невозможно представить в Байте!
Другое дело беззнаковое, тогда 128 + 1 = 129, неважно то ли это указаетль, трактуемый как целое, толи это чисто целое беззнаковое.

Дианазон -128 .. +127 и для беззнакового 0 .. 255


 
Digitman   (2003-04-16 15:27) [36]


> erikIvanov


вот это ты напрасно)

автор хочет разобраться детально, ЧТО и КАК происходит
разве это плохо ? это приветствовать надо !


 
evvcom   (2003-04-16 15:46) [37]

Сложение пройдет нормально.
Если будешь присваивать переменной Integer i := 127 (01111111b) + 1, то получишь 10000000b, а дальнейшее поведение программы будет зависеть от установленного флажка Overflow Checking (или директивы компилятора {$Q+} or {$Q-}). Если флаг установлен {$Q+}, то компилятор дальше сгенерит код проверки флага переполнения и если ..., то raise Exception. Если же компилируется с {$Q-}, то код сгенерен не будет и переменная примет значение -128 (10000000b)
Вроде понятно объяснил...

Попутно вопрос к Мастерам, например, Digitman: а как Вы получили такую медаль с надписью Мастер DELPHI? Или Вы просто являетесь создателями сего славного проекта? Или же ее все же можно заработать?
Как поется у Высоцкого: "Я, Вань, такую же хочу!"


 
Digitman   (2003-04-16 16:25) [38]

>evvcom

по поводу опций компилятора - пока о них речь не идет.

по поводу "надписи" :


> являетесь создателями сего славного проекта

нет, не являюсь


> как Вы получили такую медаль

"У меня секретов нет, слушайте, детишки !"
Просто я сподобился года 2-3 тому назад более точно процитировать Владимира Семеныча, в оригинале поющего не "ЖЕ хочу" , а "ЖУ хочу"... За что и был удостоен Фондом ув. Владимира Семеныча столь высокой награды !!) .. А собственно к Делфи оная отношения не имеет)


> ее все же можно заработать?


Безусловно !! ТОлько зачем ее "зарабатывать"-то ?? Вот еще !! Пыхтеть-то)...
Все ж гораздо тривиальней : заявки на получение сей замечательной "фенечки" подаются в "Потрепаться", там же практически без бюрократических проволочек и происходит публичная церемония "награждения")) ... Хочешь ? Имей !)... Не досталось ? Забирай мою и носи не стаптывай !) Мне не жалко))


 
evvcom   (2003-04-16 16:33) [39]

>> по поводу опций компилятора
это я для того, чтобы человеку понятно было откуда появляются "ошибки" (если вообще появляются).
А так можно складывать все, что угодно, байты они и есть байты. Главное, правильно преподнести это компилятору, чтобы не ругался, где не следует. Т.е., если я правильно понимаю задачу, то я правильно делаю преобразования типов, и компилятор это с удовольствием проглатывает.


 
Anatoly Podgoretsky   (2003-04-16 16:41) [40]

А что бы от такого не зависить, раз уж мы условилиль, что у нас это является указателем, то надо использовать BYTE.
И в реальной жизни, вместо Integer - LongWord/Cardinal



Страницы: 1 2 3 вся ветка

Форум: "Основная";
Текущий архив: 2003.05.08;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.56 MB
Время: 0.01 c
3-22972
Jaxtor
2003-04-17 11:22
2003.05.08
Параметры, InsertSQL в IBDataSet


4-23423
ers
2003-03-10 13:07
2003.05.08
Как узнать состояние окна?


3-23016
NiBL'S
2003-04-18 09:31
2003.05.08
Можно ли обойти пароль в базе gdb?


1-23170
dimonf
2003-04-24 08:43
2003.05.08
Как избавиться от стандартной прорисовки в ListBox-e???


6-23274
RUS1
2003-03-12 09:48
2003.05.08
Опять Socket-Ы :-)))!!! Ну нихрена не работает господа!!!!





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский