
Онлайн книга «Код. Тайный язык информатики»
Собранный нами компьютер состоит из реле, проводов, переключателей и лампочек. Все это — аппаратное обеспечение (hardware, или хард) компьютера. Напротив, содержащиеся в памяти коды команд и числа называются программным обеспечением (software, или софт). Когда мы говорим о компьютерах, термин «программное обеспечение» практически идентичен термину «компьютерная программа» (или просто «программа»). Написание программного обеспечения называется программированием. Именно этим я занимался, когда определял серию команд, позволяющих нашему компьютеру перемножить два числа. Как правило, в компьютерных программах мы можем различать код (который относится к самим командам) и данные, то есть числа, которыми манипулирует код. Иногда это различие не так очевидно. Например, команда «Остановить» в описанной выше последовательности выступала еще и в качестве числа –1. Компьютерное программирование иногда называют написанием кода, или кодированием. От программиста вы можете услышать фразы типа: «Я потратил свои каникулы на кодирование», «Я писал код до семи утра». Иногда компьютерных программистов называют кодерами, хотя кому-то этот термин может показаться уничижительным. Такие программисты, возможно, предпочтут, чтобы их называли программными инженерами. Коды команд, на которые реагирует процессор (например, 10h и 11h, соответствующие командам «Загрузить» и «Сохранить»), называются машинными кодами, или машинным языком. В данном случае термин «язык» используется потому, что он напоминает устный или письменный человеческий язык в том смысле, что машина его «понимает» и реагирует на него. Для обозначения команд, выполняемых нашей машиной, я использовал довольно длинные фразы вроде «Сложить с переносом». Как правило, команды — это короткие мнемонические коды, написанные заглавными буквами. Мнемокоды могут состоять всего из двух или трех букв. Далее перечислены возможные мнемокоды для команд, распознаваемых нашим компьютером. Операция Код Мнемокод Загрузить 10h LOD Сохранить 11h STO Сложить 20h ADD Вычесть 21h SUB Сложить с переносом 22h ADC Вычесть с заимствованием 23h SBB Перейти 30h JMP Перейти, если 0 31h JZ Перейти, если перенос 32h JC Перейти, если не 0 33h JNZ Перейти, если не перенос 34h JNC Остановить FFh HLT Эти мнемокоды особенно полезны, когда используются в сочетании с другими сокращенными обозначениями. Например, вместо длинной команды «Загрузить байт из ячейки 1003h в аккумулятор» можем написать следующее. LOD A,[1003h] Обозначения A и [1003h] справа от мнемокода называются аргументами, которые определяют, что конкретно происходит при выполнении команды «Загрузить». При записи аргументов место назначения указывается слева (А — аккумулятор), а источник — справа. Квадратные скобки означают, что в аккумулятор нужно загрузить не число 1003h, а значение, хранящееся в ячейке памяти по адресу 1003h. Аналогично команду «Сложить байт из ячейки 001Eh со значением в аккумуляторе» можно сократить до такого выражения. ADD A, [001Eh] А команду «Сохранить содержимое аккумулятора по адресу 1003h» — до выражения следующего вида. STO [1003h], A Обратите внимание: место назначения (ячейка памяти для команды «Сохранить») по-прежнему указывается слева, а источник — справа. Содержимое аккумулятора нужно сохранить в ячейке 1003h. Длинную команду «Перейти к ячейке 0000h, если флаг нуля не равен 1» можно записать кратко. JNZ 0000h В этой команде квадратные скобки не используются, поскольку она предполагает переход к ячейке 0000h, а не к значению, которое может в ней храниться. Такая сокращенная запись удобна, поскольку позволяет перечислить команды в столбик и сделать их легко читаемыми, не прибегая к рисованию ячеек памяти. Для указания ячейки, в которой хранится определенная команда, можете использовать шестнадцатеричный адрес с двоеточием. 0000h: LOD A, [1005h] А вот так можно указать на данные, хранящиеся по определенному адресу. 1000h: 00h, A7h 1002h: 00h, 1Ch 1004h: 00h, 00h Два байта, разделенные запятой, указывают на то, что первый хранится в ячейке по адресу слева, а второй — в ячейке, следующей за ней. Эти три строки эквивалентны следующей строке. 1000h: 00h, A7h, 00h, 1Ch, 00h, 00h Таким образом, программа для умножения двух чисел может быть записана в виде следующей серии команд. 0000h: LOD A, [1005h] ADD A, [1001h] STO [1005h], A LOD A, [1004h] ADC A, [1000h] STO [1004h], A LOD A, [1003h] ADD A, [001Eh] STO [1003h], A JNZ 0000h 001Eh: HLT 1000h: 00h, A7h 1002h: 00h, 1Ch 1004h: 00h, 00h Пустые строки и другие пробелы применяются для упрощения восприятия. При написании кода лучше не использовать фактические адреса, поскольку они могут измениться. Например, если вы решили сохранить числа в ячейках с 2000h до 20005h, то придется переписывать множество выражений. Лучше использовать метки для обозначения ячеек памяти. Эти метки — просто слова или то, что их напоминает. BEGIN: LOD A,[RESULT + 1] ADD A,[NUM1 + 1] STO [RESULT + 1], A LOD A,[RESULT] ADC A,[NUM1] STO [RESULT], A LOD A,[NUM2 + 1] ADD A,[NEG1] STO [NUM2 + 1], A JNZ BEGIN NEG1: HLT NUM1: 00h, A7h NUM2: 00h, 1Ch RESULT: 00h, 00h Важно: метки NUM1, NUM2 и RESULT ссылаются на ячейки памяти, где хранятся два байта. В приведенных выражениях метки NUM1 + 1, NUM2 + 1 и RESULT + 1 ссылаются на второй байт соответствующей метки. Обратите внимание на метку NEG1 (negative one, то есть «минус один») у команды HLT. |