//Оглавление

Первая глава без которой никак нельзя

Один из принципов машины Фон-Неймана, гласит, что код и данные хранятся в одной и той же памяти. Принцип не нов. Уже пару тысяч лет существует концепция триединого бога, троица, Бог-отец, Бог-сын, и Бог-дух святой.

Ресурсы

Основными ресурсами вычислительной машины, или, попросту говоря, компьютера являются код и данные. Код и данные это молоток и гвозди, Инь и Янь любой программы, перетекающие друг в друга согласно одному из принципов машины Фон-Неймана. Следовательно, программу можно условно разделить на две части, одна часть это данные, другая — код. И если код это документы Партии, то данные, безусловно, золото Партии.

Типы памяти и способы её распределения

Давно известно, золото Партии может быть реквизировано во время захвата власти, «дополнительная необходимость» которого может быть впоследствии экспроприирована у буржуазных элементов. Так же и память, некоторая ее часть из той что в принципе доступна программе может быть выделена непосредственно при старте, размещение такой памяти в адресном пространстве заранее известно и практически неизменно в течении всего времени работы программы. Такая память называется статической. Соответственно, данные которые находятся в статической памяти, называются статическими. Адрес статических данных остается неизменным, в течении всего времени работы программы. Та память, которая запрашивается программой у системы во время исполнения, называется динамической, соответственно, данные располагающиеся в динамической памяти называются динамическими.

Память во время работы может быть выделена в двух областях, — в куче, либо на стеке. Память выделенная на стэке адресуется смещением относительно указателя вершины стэка, который храниться в регистре ESP. Собственно, при декларации стэковой переменной компилятор генерирует код, увеличивающий фдрес ESP на размер переменной, при записи значения в переменную, компилятором генерируется код, записывающий значение в адрес памяти ESP + смещение. При выходе из функции меняется значение ESP, поэтому, программы некорректно использующие адреса стэковых переменных, например использующие адреса стэковых переменных вне функций, содержат очень мерзкую разновидность ошибок, характеризующуюся как «программа иногда не работает».

Именно потому, что код для выделения и освобождения памяти на стеке автоматически генерируется компилятором, данные, размещающиеся на стеке, называются автоматическими. К таким переменным относятся, например локальные функции переменных, или параметры функций.

Выделение памяти в куче происходит явно, т.е. код для выделения памяти пишется программистом, посредством средств языка вызовом оператора new, или одной из функций malloc например. Следует однако помнить, что не все то, что запрошено, может быть получено. По причине отсутствия, или же потому что «не положено». Что делать — выбор небольшой, попробовать обойтись без них, кого–нибудь убить, а освободившиеся ресурсы забрать себе, или застрелиться. О том что памяти может не хватить следует помнить всегда, даже несмотря на то что «уровень развития компьютерных технологий шагнул далеко вперед, и гигабайтом оперативной памяти никого уже не удивишь».В мобильных устройствах, например, памяти не так изобильно, мобильный телефон автора обладает всего 460K оперативной памяти.

Константы

Помимо обычного барахла есть и «непереходящие ценности». То есть то, значение чего никогда-никогда не меняется. В программах к «непереходящим ценностям» относятся константы. Важное примечание, не следует путать константы с константными переменными, значение последних в некоторых языках программирования, например в С++, может быть изменено, в то время как константы неизменны, а раз так, то константы относятся к статическим типам данных. Один из примеров констант — число, скажем священное для пифагорейцев число семь, или сто сорок две тысячи восемьсот пятьдесят семь.

Простейшие операции

С золотом можно делать много прикольных всяких штук, например считать, или перекладывать из одного сундука в другой. Сундуками по которым программы распихивают всякое барахло являются ячейки памяти. Типов ячеек два, «кошелек» — регистры процессора, и сарай ROM, отправку грузов в устройства IO, рассматривать не будем. Рассмотрим как «положить копеечку в кошелек», напишем простую программу в которой сделаем одну из минимально возможных операций с данными — запишем константу в регистр процессора. Совершим мы это посредством языка ассемблер и программы debug.


-a
0B61:0100 mov al,9
0B61:0102 ret
0B61:0103
-r cx
CX 0000
:3
-n short.com
-w
Запись 00003 байт
-q


Вышенаписанная программа записывает в регистр al  число 9 и завершает свою работу. При этом число 9 является частью объектного кода программы, под который при загрузке программы в системе выделяется память, это выглядит вот так:


00000000:  B0 09 C3

Размер программы равен трем байтам. Первый — B0, запись числа в регистр, второй само число в нашем случае это 09 (потому что регстр al двухбайтовый, а пустоты боится не только природа), третий — C3, завершение работы. Детальное описание корючек называемых operation codes, сокращенно opcode можно найти в Instruction Set Reference компании Intel.

Теперь модифицируем программу, так что она будет записывать 9, но теперь уже в регистр ax  и посмотрим что из этого получится.


-a
0B61:0100 mov ax, 9
0B61:0103 ret
0B61:0104
-r cx
CX 0000
:4
-n long.com
-w
Запись 00004 байт
-q


00000000:  B8 09 00 C3

Размер программы равен четырем байтам. Получается что программа, делающая на первый взгляд то же самое, что и предыдущая, на один байт больше. Это потому что число 9 в первой программе и число 9 во второй относятся к разным типам данных.

Coda

Две вышеописанные выше программы на самом деле различны. Константой во второй программе является двухбайтовое число девять 09 00. Такая форма записи числа называется Big Endian. Но об этом поговорим отдельно. Поэтому вторая перезаписывается нулями регистр ah, тогда как первая оставляет его содержимое неизменным. В этом можно легко убедиться запустив обе программы в отладчике. Набираем в командной строчке debug short.com


смотрим значения регистров, в AX=0000
-r
AX=0000  BX=0000  CX=0003  DX=0000  SP=FFFE  BP=0000  SI=0000  DI=0000
DS=0BB0  ES=0BB0  SS=0BB0  CS=0BB0  IP=0100   NV UP EI PL NZ NA PO NC
0BB0:0100 B009          MOV     AL,09

записываем в ax значение ffff
-r ax
AX 0000
:ffff

смотрим значения регистров, в AX=FFFF
-r
AX=FFFF  BX=0000  CX=0003  DX=0000  SP=FFFE  BP=0000  SI=0000  DI=0000
DS=0BB0  ES=0BB0  SS=0BB0  CS=0BB0  IP=0100   NV UP EI PL NZ NA PO NC
0BB0:0100 B009          MOV     AL,09

выполняем MOV     AL,09
-t
AX=FF09  BX=0000  CX=0003  DX=0000  SP=FFFE  BP=0000  SI=0000  DI=0000
DS=0BB0  ES=0BB0  SS=0BB0  CS=0BB0  IP=0102   NV UP EI PL NZ NA PO NC
0BB0:0102 C3            RET

значение регистра AX=FF09


-
-n s1.com
-l
-r
AX=0000  BX=0000  CX=0003  DX=0000  SP=FFFE  BP=0000  SI=0000  DI=0000
DS=0BB0  ES=0BB0  SS=0BB0  CS=0BB0  IP=0100   NV UP EI PL NZ NA PO NC
0BB0:0100 B009          MOV     AL,09
-e 100
0BB0:0100  B0.     09.B0
-r
AX=0000  BX=0000  CX=0003  DX=0000  SP=FFFE  BP=0000  SI=0000  DI=0000
DS=0BB0  ES=0BB0  SS=0BB0  CS=0BB0  IP=0100   NV UP EI PL NZ NA PO NC
0BB0:0100 B0B0          MOV     AL,B0
-t

AX=00B0  BX=0000  CX=0003  DX=0000  SP=FFFE  BP=0000  SI=0000  DI=0000
DS=0BB0  ES=0BB0  SS=0BB0  CS=0BB0  IP=0102   NV UP EI PL NZ NA PO NC
0BB0:0102 C3            RET
-