Первая глава без которой никак нельзя
Ресурсы
Основными ресурсами вычислительной машины, или, попросту говоря, компьютера являются код и данные. Код и данные это молоток и гвозди, Инь и Янь любой программы, перетекающие друг в друга согласно одному из принципов машины Фон-Неймана. Следовательно, программу можно условно разделить на две части, одна часть это данные, другая — код. И если код это документы Партии, то данные, безусловно, золото Партии.
Типы памяти и способы её распределения
Давно известно, золото Партии может быть реквизировано во время захвата власти, «дополнительная необходимость» которого может быть впоследствии экспроприирована у буржуазных элементов. Так же и память, некоторая ее часть из той что в принципе доступна программе может быть выделена непосредственно при старте, размещение такой памяти в адресном пространстве заранее известно и практически неизменно в течении всего времени работы программы. Такая память называется статической. Соответственно, данные которые находятся в статической памяти, называются статическими. Адрес статических данных остается неизменным, в течении всего времени работы программы. Та память, которая запрашивается программой у системы во время исполнения, называется динамической, соответственно, данные располагающиеся в динамической памяти называются динамическими.
Память во время работы может быть выделена в двух областях, — в куче, либо на стеке. Память выделенная на стэке адресуется смещением относительно указателя вершины стэка, который храниться в регистре 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
-