Итак, DeLorean доставил вас в США 1990 года. Как и полагается в таких случаях, в машине что-то сломалось, так что вам предстоит задержаться на некоторое время. Пока Док Браун занимается ремонтом, вам тоже надо чем-то заняться. 

Вы вспоминаете, что вы ж программист – можно заняться программированием! 

В этой статье давайте пофантазируем о том, как могло бы выглядеть программирование в 1990 году. 

Для начала нужен компьютер

Как человек прагматичный, но привыкший к некоторым удобствам, вы решаете воспользоваться ноутбуком, одной из самых доступных моделей на рынке. Это Amstrad PPC 640. 

Весит чудо техники 6 кг. Время автономной работы – шесть часов, если не пользоваться дискетниками (с ними – часа три). Вместо аккумулятора – десять батареек типа С. 

Процессор – 8088 CPU @ 4,77 MHz. Для сравнения: частота современных процессоров – в районе 3,6 GHz. 

Оперативная память – 640 Kб. Тут даже сравнивать не хочется ни с чем современным, чтобы не расстраиваться.

Жёсткого диска нет, вместо него используется дискета. У компьютера два флоппи-дисковода: на A работает операционная система и могут храниться отдельные файлы, B используется исключительно как хранилище. Кстати, вот откуда взялось название знакомого нам по Windows диска C – со времён, когда жёсткий диск ставили в довесок к флоппи-приводам A и B (следующая буква по алфавиту). 

Экран – монохромный. Размер: 640 x 200 пикселей в графическом режиме или 25 линий x 80 колонок — в текстовом. Мало!  

Операционная система – DOS 3.3. Это хорошо, ведь как программист из 2022-го вы застали DOS или по крайней мере как-то умеете пользоваться командной строкой (этого навыка будет достаточно). 

Разбираемся с программным обеспечением – без интернета

Окей, железо есть. Теперь нам нужно программное обеспечение.

И тут в повествование врывается настоящий главный герой (он же злодей и то, ради чего это всё): ассемблер.

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

Неплохой расклад: в некоторых изданиях вместе с лицензией на ассемблер в комплекте идёт мануал.

Вот так выглядела коробка издание MASM с мануалом
Вот так выглядела коробка издание MASM с мануалом

Выбираем между MASM и TASM. Решаем купить лицензию ассемблера TASM компании Borland: он полностью совместим с С++ и Turbo Pascal от той же компании (может быть полезно для нас в дальнейшем).

 Ассемблер есть. Переходим к остальному ПО.

Отладчик кода

 Берём Turbo Debugger, тоже от Borland.

Ядреные цвета нас будут преследовать еще долго
Ядреные цвета нас будут преследовать еще долго

В отладчике мы будем смотреть значения регистров, переменных и наполнение стека. С его помощью будем понимать, какая строчка привела к зависанию нашей программы (подозреваем, что такое может случиться).

Редактор

Возьмём TASMED – чтобы иметь возможность подсвечивать синтаксис разными цветами, а ещё делать сборку и запуск нашей программы.

Про ядреные цвета я не пошутил
Про ядреные цвета я не пошутил

Другие покупки (не только ПО)

Пока не ушли далеко от магазина, покупаем ещё и адаптер для нашего портативного компьютера – чтобы подключать его к телевизору и видеть наш прекрасный разукрашенный синтаксис не в монохроме, а всё-таки в цвете.

Готовимся программировать – без Stack Overflow

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

Первое, что нам будет нужно постоянно, – это список регистров процессора и их предназначение. Есть регистры, в которых можно хранить свои данные, и есть неизменяемые. Некоторые регистры разделены на подрегистры, которые содержат старшие и младшие байты. Чтобы не вспоминать каждый раз, выпишем их.

Общие регистры: используются для хранения значений (кроме BX)

16 бит

AX 

BX 

CX 

DX 

8 бит

AH

AL

BH

BL

CH

CL

DH

DL

Используется при умножении, делении и операциях ввода-вывода; оптимизирован

Может хранить как данные, так и адреса

Чаще всего используется как счётчик в циклах

Используется для операций ввода-вывода в инструкциях IN и OUT

Сегментные регистры: указатели на блоки размером 64 Кб

16 бит

CS

DS

ES

SS

Указывает на сегмент кода, в котором находится следующая вызываемая инструкция

Указывает на сегмент с операндами (данными)

Дополнительный сегмент, у которого нет конкретной цели

Указывает на сегмент стека

Адресные регистры: используются для хранения адресов

16 бит

SI 

DI

BP

Чаще всего используется в операциях переноса данных; хранит указатель на исходные данные; при операциях переноса смещается на 1; относителен сегменту DS

Чаще всего используется  в операциях переноса данных; хранит адрес переноса данных; относителен сегменту ES

Указывает на адрес базы (начала) стека; относителен сегменту SS

Регистры управления

16 бит 

SP

IP

FLAGS

Указывает на последний элемент стека; относителен сегменту SS

Указатель на следующую инструкцию; нельзя изменить или прочитать, кроме как через специальную команду перехода; относителен сегменту CS

Хранит флаги системы и результаты выполнения последней команды; регистр стоит рассматривать побитово

()-()-()-()-OF-DF-IF-TF-SF-ZF-()-AF-()-PF-()-CF

OF – флаг переполнения

DF – флаг направления

IF – флаг прерывания

TF – флаг перехвата

SF – флаг знака

ZF – флаг нуля

AF – флаг дополнительного переноса

PF – флаг чётности

CF – флаг переноса

Ещё нам понадобится список прерываний и команд MS-DOS и BIOS.

Прерывания в ассемблере – это команды, которые забирают управление у программы и передают его MS-DOS или BIOS для выполнения конкретной работы, а после завершения операции управление возвращается программе. Часто программа сама вызывает прерывание, чтобы общаться с операционной системой и BIOS или выполнять операции ввода-вывода, например, выводить текст на экран, а также считывать нажатия клавиш. 

Прерывание со своим кодом могут вызывать и сами DOS, и BIOS. Например, при делении на ноль вызовется прерывание с номером “00H”, при нажатии клавиши “PrtSc” – “05H”.

Обработка прерываний

Для обработки прерываний существует таблица векторов прерываний, в которой каждому прерыванию соответствует адрес кода, который его обрабатывает. Эти адреса можно переопределять. Данная таблица – общая для всей ОС, так что перед окончанием программы надо не забыть вернуть изначальные значения – мы не можем знать, что будет в оперативной памяти после окончания программы.

Список прерываний можно посмотреть не только в мануале, но и в специальных справочных программах, которые содержат в себе полный перечень с довольно удобным поиском. Один из самых распространённых справочников в 1990 году – “TECH Help!”.

Этот справочник будет нашим локальным интернетом. С инструкцией по TASM мы даже сможем жить без Stack Overflow.

Разбираемся со спецификой ассемблера 

В 2022 году мы пишем на высокоуровневых языках. При программировании на ассемблере в 1990-м нам нужно быть начеку – учесть ряд особенностей языка.

Первое – это типы данных, с которыми предстоит работать. Забудем про bool, int, double, string и прочие. По факту мы будем иметь дело с двумя типами: байт и слово. Слово равняется двум байтам. Это максимальная величина, которую за одну операцию может обработать 16-битный процессор. Так и определяется максимальная разрядность системы.

Если нам надо сложить два числа размером до 2 байт, мы можем это сделать с помощью одной операции, а вот сложить два четырёхбайтных числа (привычный нам int) за одну операцию не выйдет. 

В конце шестнадцатеричных чисел ставится h: например, «7A1h». Если число начинается не с цифры, то в начале ставится 0: «0FFh».

Дальше – строки. Здесь это просто последовательность байтов в кодировке ASCII. Что касается bool: бери любой понравившийся байт – и вот у тебя целых 8 бит, или восемь булевых значений. А если ты тру-хардкор-ассемблист, то будешь использовать каждый бит, группируя все флаги в нескольких байтах.

Также у нас могут быть, кхм, некоторые сложности с числами с плавающей точкой. В первую очередь из-за весьма вероятного отсутствия математического сопроцессора 8087, который в 1990 году есть далеко не на всех компьютерах. В будущем процессоры будут включать в себя этот самый 8087, но, пока у нас его нет, будем обходить числа с плавающей точкой стороной.

Создать переменную и обратиться к ней можно так:

; BYTE
someByte DB ?; Выделить байт с неопределённым значением (теоретически может оказаться мусором)
someString DB 'Some text'; Ассемблер сам определит длину строки и выделит необходимое количество байтов. Помним, что в ASCII один символ весит 1 байт
MOV someByte, AL; Запишем в переменную someByte значение регистра AL

; WORD
someWord DW 0FFAH; Выделим 2 байта и присвоим им значение FFA (4090 в десятичной системе)
MOV AX, someWord; Запишем в регистр AX значение переменной someWord
 
;ARRAY
someByteArray DB 10 DUP(5); Выделим десять ячеек по одному байту и запишем в каждую ячейку число 5 в десятичной форме
MOV someByteArray[2], AH; Запишем в третью (отсчёт идёт с нуля) ячейку массива someByteArray значение регистра AH

; POINTERS
MOV BX, OFFSET someByte; Запишем в регистр BX адрес someByte. Несмотря на то, что переменная хранит байт, адрес всегда содержит два байта (зависит от разрядности системы)
MOV someByteArray[0], BYTE PTR[BX]; Прочитаем байт из адреса, хранящегося в регистре BX, и запишем его в первый элемент массива
MOV BYTE PTR[BX], 0F1H; Запишем 1 байт со значением 0F1H в ячейку памяти по адресу из регистра BX

В ассемблере нет привычных нам конструкций из высокоуровневых языков: if/else, for/while. На этом моменте может показаться, что вот теперь-то мы влипли окончательно. Но не всё так плохо. Не зря учебное пособие по TASM начинается так:

Возможно, вы слышали, что программирование на языке ассемблера – это чёрная магия, подходящая только для хакеров и волшебников. Однако ассемблер – это не что иное, как компьютерный язык, который понятен человеку. И стоит ожидать, что язык компьютера в высшей степени логичен. Язык ассемблера очень мощный! Фактически язык ассемблера – это единственный способ использовать всю мощь семейства Intel 80x86, процессоров, лежащих в основе IBM-совместимых ПК.

Преисполнившись энтузиазмом стать чёрным магом, продолжаем погружение.

Вместо if/else в ассемблере используется система условных и безусловных переходов к определёнными отметкам кода. Такой подход кажется знакомым по школьным урокам информатики, где на Pascal или Basic мы писали конструкции GOTO.

Вариантов условных переходов много, и все они смотрят на флаги из регистра управления FLAGS. Безусловный – только оператор JMP. Флаги выставляются после команд сравнения (CMP, TEST), после математических операций (ADD, SUB) и после прерываний. Формат команды: JXX <метка>.

У TASM есть режим Ideal. В него входят дополнительные конструкции, которые есть только у данного ассемблера. И среди них есть привычная нам if/else. Но поскольку режим Ideal – это особенность только лишь TASM, мы его рассматривать не будем.

Вот пример проверки значения регистра BX на чётность/нечётность:

TEST BX,1 ;Логическое побитовое «И» между двумя операндами (число чётное, если последний бит равен 0)
JZ EVEN_ROW_CALL ; Переход, если флаг ZF равен 1. Флаг ZF равен 1, если результат предыдущей команды равен 0
JNZ ODD_ROW_CALL ; Переход, если флаг ZF равен 0
EVEN_ROW_CALL: ; Метка кода
	; …SOME EVEN LOGIC…
	JMP END_ALL ; Безусловный переход в конец
ODD_ROW_CALL: ; Метка кода
	; …SOME ODD LOGIC…
END_ALL: ; Метка кода
; Continue...

А вот с for/while всё намного проще и привычнее. Есть конструкция LOOP. Она переходит на определённую метку, если регистр CX не равен 0. Формат команды: LOOP <метка>.

Пример LOOP:

; some code…
index DW 0
MOV CX, 100 ; Задаём количество циклов
MY_LOOP:
	; …SOME LOOP LOGIC…
	INC index; Увеличиваем счётчик
	LOOP MY_LOOP; CX автоматически уменьшается на 1
; Continue…

C функциями всё проще и сложнее одновременно. У ассемблера есть ключевые слова. PROC указывает на начало процедуры, ENDP – на окончание. Выйти из процедуры можно с помощью команды RET. 

Общий синтаксис такой:

<имя> PROC
	; SOME PROCEDURE LOGIC
	RET <число>
<имя> ENDP

Для вызова процедуры используется команда CALL. Формат команды: CALL <имя процедуры>.

А вот теперь начнётся настоящее веселье: передача параметров и возврат значений. Для входных параметров можно использовать регистры. Но их всего четыре, чего часто бывает недостаточно. Да и можно запутаться, какие регистры ты изменил, а какие – ещё нет. Для решения этой проблемы есть стек.

Стек – это участок памяти, который реализует принцип «первый вошёл, последний вышел». Каждая ячейка стека содержит в себе одно слово: 2 байта. Для работы со стеком используются две команды: PUSH – для записи значения в стек; POP – для получения значения из него. Регистр BP указывает на начало стека, SP – на его последний элемент. Регистры BP и SP относительны сегменту SS. 

Вот так выглядит метод, который принимает два параметра:

; Определение процедуры
SOME_PROC PROC NEAR
     PUSH BP;
     MOV BP, SS:SP; Переносим значение начала стека в регистр BP, так как он может хранить адрес
     PUSH AX; Сохраняем регистр

     firstParam equ [BP + 4]; Параметры начинаются со второго элемента, так как при вызове процедуры в стек записывается адрес команды, к которой надо вернуться после завершения процедуры, и ещё 2 байта из-за сохранённого BP
     secondParam equ [BP + 6]

     MOV AX, secondParam; Изменяем регистр

     ; …SOME PROCEDURE LOGIC…

     POP AX; Возвращаем значение регистра, которое было до начала процедуры
     POP BP;
     RET 4; Если с RET передать число, то в стеке очистится такое количество байтов (в нашем случае – два параметра по 2 байта)
SOME_PROC ENDP
; Вызов процедуры
PUSH 10
PUSH OFFSET someVariable
CALL secondParam 

Ого, если придётся делать всю эту жуть в каждой процедуре, то можно сойти с ума. Если добавится параметр, надо не забыть поменять число в RET и следить за тем, чтобы количество операций записи в стек и чтения из него всегда совпадало. Очень легко ошибиться при вычислении адреса переменных. А ещё нужно сохранять регистры, чтобы процедура не влияла на всю программу. Вычисления превращаются в кошмар! 

Чтобы не стрелять себе в ногу, в ассемблере TASM есть прекрасные макросы, которые не только упрощают написание процедур, но и делают их совместимыми с Turbo Pascal и Borland C++. Несмотря на то, что это макросы из TASM, в других ассемблерах они либо идентичны, либо очень на них похожи. Например, этот синтаксис будет MASM-совместимым.

Вот так будет выглядеть процедура, которая использует макросы:

SOME_PROC PROC PASCAL; Указываем, с каким языком будет совместим этот метод
ARG firstParam:WORD, secondParam:WORD; Входные параметры и их типы
USES AX; Сохраняем регистры в стеке, чтобы при завершении процедуры восстановить их изначальные значения


	MOV AX, secondParam
	; …SOME PROCEDURE LOGIC…

	RET; Больше не надо никаких чисел
SOME_PROC  ENDP
; Лёгкий вызов процедуры
CALL SOME_PROC PASCAL, 10, OFFSET someVariable; Не забываем прописать режим совместимости с языком
; Это необходимо, поскольку у разных языков разная последовательность входных параметров. 
; Также у разных языков очисткой стека занимается либо сама процедура, либо вызывающий её код

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

Чтобы упростить себе жизнь, будем относиться к ассемблеру как к процедурному языку вроде С. Процедуры, определение кастомных типов – ассемблер это умеет. Справедливости ради стоит сказать, что ассемблер умеет и в ООП, но это крайне неудобно: как правило, используется только для комбинации с С++. 

PERSON STRUC
	name DB 'Alex'; Значения по умолчанию
	age DB 20
	salary DW ?
PERSON ENDS
boss PERSON<,?,1000>; name по умолчанию, age неизвестен, salary – 1000
; Это эквивалентно 
;	name DB 'Alex'
;	age DB ?
;	salary DB 1000
MOV AX, boss.salary ; Обращение к элементу структуры

У TASM есть ещё много возможностей, которые могут упростить написание кода, но на данном этапе нам будет достаточно тех, которые мы обсудили. Будем считать, что весь необходимый инструментарий у нас есть.

Приступаем к чёрной магии. Позаботимся о чистоте кода  

Когда мы начинаем программировать, понимаем, почему у ассемблера репутация «чёрной магии». Волшебные числа, мистические метки, странные операции. Ассемблер не интуитивен. 

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

Первое и одно из ключевых условий порядка в коде – это говорящие названия методов. 

Дальше: 

  • любое прерывание будем оборачивать в метод;

  • будем разбивать код на блоки или отдельные файлы;

  • вместо магических чисел станем объявлять их названия через EQU; за длину названий можно не переживать, так как транслятор заменит все метки на их значения.

Вот пример того, как может выглядеть код на ассемблере: 

; main.asm
DATASEG
actualVideoMode DB 0

CODESEG
START:
;=====================CONSTS=================
BIOS_VIDEO_INTERRUPT EQU 10H; Объявим константы, которые заменят магические числа
BIOS_KEYBOARD_INTERRUPT EQU 16H
DOS_INERRUPT EQU 21H
;============================================

CALL SAVE_CURRENT_VIDEO_MODE PASCAL, OFFSET actualVideoMode 
CALL CGA_MODE; Если процедура не принимает параметров, то можно опустить ключевое слово совместимости с языком

; DO SOME DRAWING

CALL WAIT_KEY
CALL RESTORE_VIDEO_MODE PASCAL, actualVideoMode; Восстановим изначальный видеорежим перед окончанием программы
CALL TERMINATE

INCLUDE utils.asm; Транслятор вставит сюда весь код из файла
END START
; utils.asm
CGA_MODE PROC PASCAL
USES AX,BX
      CGA_COLOR_MODE EQU 4

	MOV AX,CGA_COLOR_MODE  ; CGA 320x200 4color
	INT BIOS_VIDEO_INTERRUPT
	RET
CGA_MODE ENDP

RESTORE_VIDEO_MODE PROC PASCAL 
ARG videoMode:WORD
USES AX
	MOV AX,videoMode
	INT BIOS_VIDEO_INTERRUPT
	RET
RESTORE_VIDEO_MODE ENDP
	
WAIT_KEY PROC PASCAL
USES AX
	WAIT_ANY_KEY_COMMAND_CODE EQU 00H

	MOV AH,WAIT_ANY_KEY_COMMAND_CODE 
	INT BIOS_KEYBOARD_INTERRUPT
	RET
WAIT_KEY ENDP

SAVE_CURRENT_VIDEO_MODE PROC PASCAL
ARG currentModePtr:WORD
USES AX,BX
	CURRENT_VIDEO_MODE_CODE EQU 0FH

	MOV BX,currentModePtr
	XOR AX,AX
	MOV AH,CURRENT_VIDEO_MODE_CODE
	INT DOS_INERRUPT
	MOV BYTE PTR [BX],AL
	RET
SAVE_CURRENT_VIDEO_MODE ENDP

TERMINATE PROC PASCAL
USES AX
	TEMINATE_COMMAND_CODE EQU 4C00H

	MOV AX,TEMINATE_COMMAND_CODE 
	INT DOS_INERRUPT
	RET
TERMINATE ENDP

Даже не понимая, что происходит в процедурах, можно легко разобраться, что делает программа. А самое важное – код теперь не выглядит страшно. Я бы даже сказал, что видел намного более страшные и запутанные SQL-процедуры.

Чёрная магия вблизи: сильные и слабые стороны ассемблера  

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

Но есть и недостатки. На ассемблере крайне неудобно писать бизнес-логику. Он заставит вас из раза в раз повторять рутинные операции, например выделение и освобождение памяти, в результате чего получится код большего объёма, чем на высокоуровневых языках.

Но есть вещи, которые ассемблер делает лучше всех. Это, например, общение с периферией. Надо написать драйвер? Драйвер должен быть максимально быстрым и потреблять минимум ресурсов? В этом ассемблер вам поможет. Надо что-то вывести на экран, нарисовать линию, текст или отрисовать картинку? Ассемблер хорош и в этом: можно использовать как отдельные прерывания, так и писать в видеопамять напрямую (на самом деле вы будете писать в оперативную память, участок которой мапится с видеопамятью, но это мелочи жизни). Запись напрямую в видеопамять выглядит как весьма производительный способ что-либо показать на экране, правда? Ещё мы можем прочитать данные с экрана. Не уверен, что такое может пригодиться, но возможность есть! 

И тут мы подходим к одному из главных преимуществ ассемблера: мы можем сами решать, где и что оптимизировать. 

Например, мы хотим вывести изображение из файла на экран. Допустим, файл заранее подготовлен и представлен в бинарном виде, где каждым двум битам соответствует один цвет (графический режим у CGA-экранов имеет всего две палитры по четыре цвета). 

Изображение на монохромном CGA-экране
Изображение на монохромном CGA-экране
А вот так – в цвете
А вот так – в цвете

Мы можем пойти двумя путями.

Первый – это прочитать сразу весь файл, сохранить его в буфер, а уже из буфера перенести в видеопамять. Такой подход будет самым быстрым, так как потребует совершения наименьшего количества операций (конечно, мы могли бы обратиться к диску в обход операционной системы, но кажется, тут игра не стоит свеч). Минус такого подхода заключается в том, что нам в какой-то момент придётся хранить в оперативной памяти весь файл. А мы как-никак в 1990 году: не можем похвастаться, что у нас в распоряжении так уж много памяти. 

Второй путь – это читать файл побайтово и сразу записывать его в видеопамять. В таком случае размер буфера будет всего 1 байт. За экономию места придётся заплатить скоростью, потому что теперь для каждого байта нужно вызывать команду чтения файла.

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

Назад в будущее

Док Браун вернул вас домой – в мир высокоуровневых языков, многопоточности, десятков гигабайтов оперативки и терабайтов жёсткого диска. 

Винтажные компьютеры, DOS – чему разработчика из 2022 года мог научить опыт программирования в 1990-м? 

Мы копнули вглубь разработки, спустились вниз на несколько уровней. Увидели, как программа общается с операционной системой и с процессором. Вспомнили бинарные операции: AND, OR, XOR, сдвиги влево и вправо (могут заменять целочисленное умножение и деление на 2). 

Всё это крайне познавательно. Но есть ли тут практическая польза для разработчика из 2022 года? 

Навскидку: ассемблер и .NET

При компиляции любого .NET-приложения генерируется код Intermediate Language (IL). Во время выполнения программы IL-код транслируется в нативный код через компилятор Just-In-Time (JIT). Представим себе ситуацию, когда нам хочется понять, что наделал этот JIT. 

Нативный код мы прочитать не сможем – нули и единицы выглядят живописно, но не слишком информативно для человеческого глаза. Давайте лучше заглянем в Disassembly от Microsoft (или просто дизассемблер). Там мы найдём листинг на ассемблере, который полностью соответствует нативному коду. И вот тут понимание ассемблера очень пригодится. 

На learn.microsoft.com в разделе про дизассемблер даже есть такая плашка:

Чтобы использовать возможности дизассемблера по максимуму, требуются базовые знания программирования на ассемблере.

Пример дизассемблирования
Пример дизассемблирования

Конечно, дизассемблить код приходится не так уж часто. Многие .NET-разработчики совершенно справедливо никогда этого не делали.

В дизассемблер вас может привести желание написать некоторый суперпроизводительный код или (почему бы и нет?) хакнуть .NET. Это не так уж и сложно. Например, можно заменить вообще любой метод на другой во всей программе.

using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

namespace HackTest;

public class Program
{
    sealed public class A
    {
        public string LocalParam = "LocalParam";
        public void WriteA(string d)
        {
            Console.WriteLine($"Method A {d}");
        }
    }

    public class B
    {
        public void WriteB(string d)
        {
            var valueFromA = ((A)(object)this).LocalParam;// Доступ к родительскому классу тоже есть
            Console.WriteLine($"Method B {d} with {valueFromA}");
        }
    }

    public static void Main(string[] args)
    {
        var a = new A();
        HackReplace(typeof(A).GetMethod("WriteA"), typeof(B).GetMethod("WriteB"));// Это замена навсегда. Можно сохранять ссылку на изначальный метод и заменять её обратно
        a.WriteA("TEST"); // Посмотрите в консоли, что выведется :)
    }

    public static void HackReplace(MethodBase source, MethodBase dest)
    {
        RuntimeHelpers.PrepareMethod(source.MethodHandle); // Чтобы замена сработала, JIT-компилятор должен генерировать нативный код для метода – мы будем его менять
        RuntimeHelpers.PrepareMethod(dest.MethodHandle);

        var firtPrt = source.MethodHandle.GetFunctionPointer(); // Получаем указатель на метод
        var secondPrt = dest.MethodHandle.GetFunctionPointer().ToInt64(); // Говорим, что нам надо относиться к указателю как к обычному long-значению
        var sourcePtrEnd = firtPrt.ToInt64() + 1 + 4; // Нам нужно вычислить offset к следующей инструкции

        Marshal.WriteIntPtr(firtPrt + 1, new IntPtr(secondPrt - sourcePtrEnd));
    }
}

Пример хака; и даже без unsafe

В примере выше мы, по сути, заменяем одну команду на другую в нативном коде. Без знания ассемблера разобраться будет непросто. Например, будет непонятно, откуда взялись волшебные числа 1 и 4.

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

№	Нативный код		Ассемблерный код
1	00007FF7A2E642A3  	mov	byte ptr [0000000200007FF7h],al  
2	00007FF7A2E642AC  	add	byte ptr [rax],al  
3	00007FF7A2E642AE  	add	byte ptr [rax],al  
4	00007FF7A2E642B0  	jmp	HackTest.Program+A.WriteA()(07FF7A2E64820h)
5	00007FF7A2E642B5  	pop	rdi  
6	00007FF7A2E642B6  	add	byte ptr [rcx],al  
7	00007FF7A2E642B8  	jmp	HackTest.Program+A..ctor()(07FF7A2E647C0h)
8	00007FF7A2E642BD  	pop	rdi  
9	00007FF7A2E642BE  	add	eax,dword ptr [rax]  
10	00007FF7A2E642C0  	adc	byte ptr [rax+7FF7A2EEh],bh 

Чтобы узнать полную длину команды, надо из адреса следующей команды вычесть адрес искомой. В нашем случае – из адреса строки 5 вычесть адрес строки 4. Возьмём две последние цифры и получим: B5-B0=5. Один байт – это сама команда JMP, а остальные четыре хранят разницу между следующей по порядку командой и командой, на которую нужно перепрыгнуть. Вот эти четыре байта мы и заменяем. Помещаем туда разницу между следующей командой и командой по вызову метода WriteB. В итоге эта JMP перепрыгивает на JMP HackTest.Program+B.WriteB(), которая уже и вызывает нужный метод. 

Работает это настолько хорошо, что даже breakpoint при дебаге там останавливается и в stack trace отображает всё корректно: 

Unhandled exception. System.NotImplementedException: The method or operation is not implemented.
   at HackTest.Program.B.WriteB() in C:\Users\Mike\source\repos\HackTest\HackTest\Program.cs:line 21
   at HackTest.Program.Main(String[] args) in C:\Users\Mike\source\repos\HackTest\HackTest\Program.cs:line 29

Стоит сказать, что такой хак может по-разному работать на разных процессорах и версиях .NET. Представленная выше реализация актуальна для x64 и .NET 6. В идеале она должна работать и на x32 и других версиях .NET начиная с .NET Core 2.0. А вот за работу на .NET Framework и архитектуре ARM поручиться не могу.

Если покопаться, можно делать и многое другое. Например – декорировать методы. Такие хаки особенно актуальны, когда надо обернуть какой-нибудь sealed-метод сторонней библиотеки. Например, можно добавить шифрование и логирование в методы, в которых они не предусмотрены.

Ассемблер не только в .NET

Ассемблер жив сам по себе! До сих пор можно встретить свежий код, намеренно написанный на ассемблере – если требуется максимальная производительность.

Если посмотреть на список самых популярных языков по версии TIOBE, то там ассемблер занимает строчку между JS и SQL:

Да, TASM уже давно мёртв (хотя вы всё ещё можете написать на нём 32-битное приложение под Windows). Но есть другие ассемблеры: MASM, GAS, NASM. 

Нужно сделать максимально быстрый обработчик видеопотока? Ассемблер вам в помощь. Хотите написать драйвер? Опять обращайтесь к ассемблеру.

Большое направление программирования на ассемблере – это написание программ для микроконтроллеров. У этих девайсов обычно большие ограничения по мощности процессора и объёму памяти, так что в этом случае ассемблер – это не альтернатива, а единственное средство решения задачи.

Ассемблер на все времена  

С 1990 года многое изменилось: железо стало мощнее, софт – разнообразнее и удобнее, появились новые языки программирования.

Ассемблер ещё тогда в 1990-м считали чёрной магией (помните напутствие из мануала TASM?). А сейчас и подавно: кажется, зачем этот входной порог и приседания, если под рукой столько более комфортных инструментов? 

Но не так страшен ассемблер, как его репутация. Хардкор в .NET, микроконтроллеры, низкоуровневые оптимизации – областей применения хватает и по сей день. И старый добрый ассемблер по-прежнему помогает делать крутые вещи.

Возможно, в путешествии с Доком Брауном в наше будущее мы увидим, как искусственный интеллект пишет код вместо людей и творятся разные другие чудеса программирования. Но не удивлюсь, если и там нам доведётся встретить ассемблер – живой и здоровый.

Комментарии (147)


  1. OptimumOption
    30.11.2022 08:52
    +2

    "...пока не ушли далеко от магазина, покупаем ещё и адаптер для нашего портативного компьютера – чтобы подключать его к телевизору и видеть наш прекрасный разукрашенный синтаксис не в монохроме, а всё-таки в цвете..." - читер! :)


    1. BlueBeard
      30.11.2022 15:21

      адаптер дорого, также как и нормальный монитор, самые продвинутые писали TSR, который после переключения видеорежимов подстраивала частоты разверток перепрограммируя видеокарту


      1. PuerteMuerte
        30.11.2022 15:37
        +6

        Это ж CGA, оно изначально работает на телевизионной частоте развертки, там для подключения к ТВ достаточно было смешать сигналы синхронизации и цвета, ну и резистором уровень сигнала понизить с TTL до телевизионного.


  1. dyadyaSerezha
    30.11.2022 09:03
    +17

    1. В 1990 были уже вполне себе нормальные PC-шки, а не тот монстр, что показал автор.

    2. В магазине ничего этого купить было нельзя. Доставали через знакомых, за бешеные деньги.

    3. Зачем же фантазировать? Я в 1990 программировал вполне успешно и профессионально, в том числе и на Ассемблере.)


    1. AseevAndrew05
      30.11.2022 09:39
      +7

      По второму пункту может в США 1990 году и можно было всё это купить

      Первое предложение статьи: "Итак, DeLorean доставил вас в США 1990 года."


      1. SADKO
        30.11.2022 11:13

        Тут ещё есть нюанс того как работали компьютерные магазины в США, какой был ассортимент и причём здесь PC 640 ;-) а так-же CGA => TV в стране с NTSC, не адаптеры и шнурки были, но годами ранее...


      1. dyadyaSerezha
        30.11.2022 11:15

        Точно, блин. Пропустил. Но тогда тем более был ассортимент получше того монстра.


        1. axe_chita
          30.11.2022 18:52
          +1

          Да нифига подобного, уже находили проспект рождественской распродажи 1991 года, так там вполне были востребованы ХТ@10mHz с CGA мониторами соответственно по 699,99$ за системник и 229,99$ за монитор.
          Так что с ассортиментом «не всё так однозначно» ;)


          1. salnicoff
            30.11.2022 20:21

            XT в то время можно было на терминалы для банковских клерков пустить. Или учить детишек основам программирования в школах... Короче, что-то вроде современных «малинок» было.


            1. axe_chita
              30.11.2022 21:03
              +1

              На ХТ можно было вполне успешно работать как в бизнес сфере, Lotus/SuperCalc, так и в программировании на ТР, ТС и присоединившимся к ним ТВ.
              А терминалов на КР580 в СССР и так хватало;)


              1. salnicoff
                30.11.2022 21:20

                На ХТ можно было вполне успешно работать как в бизнес сфере, Lotus/SuperCalc

                Если повезет, то можно. Ну или старые версии использовать. Просто в какой-то момент пошла мода использовать в реальном режиме инструкции, которые были только в 286 и выше. Ну и часть софта под DOS научилась использовать память за пределом первого мегабайта, что существенно ускоряло их работу, а XT во второй мегабайт лазать не умел от слова «совсем»...


                1. axe_chita
                  30.11.2022 22:17
                  +3

                  Если повезет, то можно. Ну или старые версии использовать.
                  А зачем было везти? ТР7 отлично работал с ООП и TV, обычный Си в лице ТС2.0 был беспроблемным, на ТС++ 1.1 тоже было вполне нормально писать. Да и все спредшиты работали на 8086, кому охота терять больше четверти рынка США?
                  Просто в какой-то момент пошла мода использовать в реальном режиме инструкции, которые были только в 286 и выше.
                  Ну у «тормозов» были свои причуды. Нормальные наСИльники и Пасквилянты при тормозах переписывали критические части, кто бы мог подумать, на чистом 8086 ассемблере «ибо нефиг страдать фигней».
                  Ну и часть софта под DOS научилась использовать память за пределом первого мегабайта
                  Только на АТ286 и выше, и только с появлением MS-DOS 5 (1991 год). Навскидку вспомню из DOS программ активно использовавших XMS только DN и QuattroPro. RamDrive/Ncache/Smartdrv не в счет.
                  что существенно ускоряло их работу, а XT во второй мегабайт лазать не умел от слова «совсем»...
                  А для решения этой проблемы имелся стандарт EMS, который был поддержан куда шире как с аппаратной стороны: были Турбо-ХТ с 2мб памяти где не используемый остаток памяти в 1408кб можно было задействовать как EMS, или купить плату расширения EMS нужного объема. Так и с программной, вплоть до того что оверлеи программ загружались в EMS и вызывались от туда. А уж как любили EMS электронные таблицы и редакторы текста! Так что: Да, но нет. И это без учета того, что можно было из этой EMS создать UMB вверху, переместить наверх DOS, драйвера и резиденты и получить внизу почти 639кб.


                  1. salnicoff
                    30.11.2022 22:28

                    ТР7 отлично работал с ООП и TV, обычный Си в лице ТС2.0 был беспроблемным, на ТС++ 1.1 тоже было вполне нормально писать.

                    Эти-то работали, да.

                     Да и все спредшиты работали на 8086, кому охота терять больше четверти рынка США?

                    Сейчас, наверное, уже не вспомню, но кто-то падал, как раз из-за применения 286-ых инструкций. И решение — либо апгрейд машины, либо даунгрейд версии.

                    А EMS... Да, было. Знатный костыль. Все с него на XMS бежали, если была возможность. Хотя тоже костыль...


                    1. axe_chita
                      30.11.2022 23:23
                      +1

                      Эти-то работали, да.
                      TP 7 was released on 27 October 1992. TC2.0 (late 1988). Turbo C++ 1.0 (in 1990). Вполне актуальные программы разработки рубежа 90-х годов
                      Сейчас, наверное, уже не вспомню, но кто-то падал, как раз из-за применения 286-ых инструкций. И решение — либо апгрейд машины, либо даунгрейд версии.
                      Не помню таких. В те времена, было хорошим тоном, проверять тип процессора при старте если ты использовал инструкции выше 8086 (NEC V20 и выше), и в случае не исполнения условия выдавал предупреждение и завершал работу программы. А падение без предупреждения, признак… пониженной социальной ответственности. Да и выигрыш, от использования 286 инструкций, часто не превосходил в среднем 5-7%.
                      А EMS… Да, было. Знатный костыль. Все с него на XMS бежали, если была возможность. Хотя тоже костыль...
                      Костыля бы не было, если бы IBM изначально не решило что 640кб будет достаточно всем, и не сделало архитектуру памяти PC изначально с переключаемыми страницами памяти.
                      И наоборот, EMS4 был ясен и понятен, окно доступа к EMS могло располагаться везде, а не только в 64кб выше первого мегабайта в XMS. Так что всё было, с точностью до наоборот.


                      1. Hlad
                        01.12.2022 10:00

                        Небольшое уточнение: "падение программы" - это термин уже многозадачных ОС. А в ДОСе тупо вис компьютер, и как хочешь, так и разбирайся, что там случилось.


                      1. axe_chita
                        01.12.2022 10:40

                        У 8086 не было исключения/прерывания недействительный код операции. просто следующий код в конвеере считался кодом операции. А там как повезет.
                        И разбирались с такими «висяками» натравливая на этих подозрительных AFD и Sourcer.


                  1. voted
                    01.12.2022 13:42

                    ТР7 отлично работал с ООП и TV

                    TP7 не работал на 80186 (в начале 00х достался списанный навороченный "Поиск" с винтом на 10Мб и флопиками 5.25 на лето в деревне), специально с интернета скачивал разные версии, самая последняя которая запустилась была TP5.5, на 80286 проблем с запуском ТР7 уже не было, так что я сомневаюсь что ТР7 работал бы на 8088


                    1. axe_chita
                      01.12.2022 14:43
                      +2

                      TurboXT Siemens 8088@12mHz/640kb/HGC/CGA/5.25x2 — 360kb/hdd mfm 20mb — никаких проблем с запуском и работой с IDE Turbo и компилятором TPC. IDE TPX идущая в комплекте ТР7, требует для запуска DPMI и 286 процессор и 2 мегабайта памяти для работы в protected mode.
                      Так что, что то вы запутались;) Турбина, работала на 8088 на раз.
                      специально нашел системные требования ТР7
                      «System Requirements
                      For the IBM® family of personal computers and all 100% compatibles
                      512K RAM minimum

                      Two floppy disk drives or hard disk required for Turbo IDE
                      High-capacity IDE requires 80286 or higher processor, 2Mb of memory, and hard disk
                      Mouse support requires Microsoft® mouse or compatible driver, version 6.0 or later»


                      1. voted
                        02.12.2022 12:48
                        +2

                        Похоже действительно запутался, возможно ложные воспоминания. Но отложилось что неделю искал варианты как скачать ТР7.0 а он не запустился, может действительно TPX пробовал, но поидее TURBO.EXE, может там надо было что то настроить, переключить. Эх больше 20 лет назад было. Сейчас даже захотелось полезть на чердак, оживить тот компьютер и проверить с текущим багажом знаний :)

                        Увы чердак в >3000 км сейчас от меня и в 30 км от линии фронта, посему когда появиться возможность (если к тому времени не забуду конечно) - поеду и проверю.


                      1. axe_chita
                        02.12.2022 15:29
                        +1

                        Бывает, хотя много времени прошло, у меня уже четверть века назад. Последний раз я на них кодил еще до того как Win95 вышел.
                        Охренеть… Как время летит…


                    1. PuerteMuerte
                      01.12.2022 17:13
                      +2

                      TP7 не работал на 80186 (в начале 00х достался списанный навороченный "Поиск" с винтом на 10Мб и флопиками 5.25 на лето в деревне

                      У меня в 90-е был Поиск-1, самый простейший из ХТ-совместимых клонов, без винта, 608К ОЗУ, КМ1810ВМ88 процессор, один дисковод 720К. Так вот, даже на нём работал TP7, хотя с подсветкой синтаксиса и тормозил нещадно. Другое дело, что в комплекте ТР7 были ещё и компиляторы для защищённого режима, которые на ХТ уже не работали. Но для ООП можно было и ТР5.5 юзать, там уже оно появилось.


            1. axe_chita
              30.11.2022 21:04

              дубль


          1. dyadyaSerezha
            30.11.2022 21:26

            Как ни фига подобного, когда это только подтвердлает мою мысль.


            1. axe_chita
              30.11.2022 22:06

              Вы на IBM PS/1 из этого же буклета посмотрите и прослезитесь.


              1. dyadyaSerezha
                30.11.2022 22:22

                Распродажи разве бывают.


                1. axe_chita
                  30.11.2022 23:24

                  Бывают — это фантастика;)


          1. swapper9
            30.11.2022 22:05
            +1

            и "рыночный" курс доллара в СССР в конце 1991г. порядка 100р за 1$. и того системник 70000руб :) А я тем временем в 1990г. купил первый ПК (пусть и не PC-совместимый), но тем не менее БК0010-01 за 650руб)


            1. dyadyaSerezha
              30.11.2022 22:26
              +1

              Да, ПК тогда стоил почти как машина. Мы покупали их в очень малых количествах на работу (деньги у оборонки были) и записывались в очередь на поработать) Я тогда тоже купил БК0010, думал написать биоритмы и разбогатеть быстро, сидя у какого-нибудь большого магазина и рассчитывая биоритмы зевакам за деньги. Но что-то пошло не так...)


              1. salnicoff
                30.11.2022 22:29

                Надо было на вокзал, и гороскопы продавать... :-)


                1. dyadyaSerezha
                  01.12.2022 14:52

                  Да банально давать поиграться на время на вокзале - сейчас бы уже миллиардером был... В-)


      1. addewyd
        02.12.2022 13:59

        в 90м у меня был ес-1840, а в 91 уже 1841 с цветным монитором и винтом на 20 Мб.


    1. PuerteMuerte
      30.11.2022 12:59
      +1

      Тот монстр был в иностранных магазинах, по монстроидальной цене даже для иностранцев (а что, это же ноутбук!), и чуть пораньше, чем в 1990. У нас в это время в магазине или на радиорынке худо-бедно можно было купить "Поиск", "Электронику МС 1502" или "Ассистент-128", ну и в общем-то можно было программировать даже на Турбо-Паскале 5.5 или Турбо Сях++, и почти по-современному, с блэкджеком, ООП и фреймворком Турбо Вижн.


    1. sepulkary
      30.11.2022 15:57
      +4

      Да, я тоже с 1998 по примерно 2002 писал на ассемблере для PIC и i51, спасибо автору за нахлынувшие приятные воспоминания :)

      Насчёт контринтуитивности ассемблера не соглашусь. Да, когнитивная нагрузка неслабая, но ассемблер - это, фактически, окно в процессор с минимумом промежуточных абстракций. Я наоборот, в то время читал Страуструпа и по молодости недоумевал, зачем такие усложнения :)


      1. kuza2000
        30.11.2022 22:25
        +2

        Примерно в те годы после ассемблера C изучал, заставляя его формировать код, который мне нужно на ассемблере)) Писал на С, и смотрел во что компилируется. Добивался, что бы было что нужно. В основном получалось, правда много лишних команд загрузки из памяти в регистры вставлял...


  1. SlFed
    30.11.2022 10:45
    +6

    Но есть вещи, которые ассемблер делает лучше всех.

    Лучше всего на ассемблере было писать резидентные программы для DOS. Драйверов в 1990 году еще почти не требовалось. Все оборудование было стандартным и программы напрямую обращались к портам.

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


    1. avaava
      30.11.2022 10:52
      +5

      Вот тоже не понятно. Паскаль, как язык, уже был. И даже работал на отечественных клонах 8086. Я, конечно, увидел это позже, чем в 1990 (тогда было ОЧЕНЬ дорого, но было). А писать на паскале намного приятнее (пробовал). Там уже были высокоуровневые процедуры, подключаемые модули, даже оверлеи (или это было позже?). И вставки на том же ассемблере где надо позволяли обходиться малой кровью. И да, писать прямо в видеопамять тогда было можно, иногда даже нужно. Работало как магия.


      1. SlFed
        30.11.2022 11:23
        +1

        Там уже были высокоуровневые процедуры, подключаемые модули, даже оверлеи (или это было позже?)

        Все это было вроде с 5 версии.

        И вставки на том же ассемблере

        А это с 6 версии. До этого только вставки машинных кодов.

        Единственно чего не позволял турбо паскаль - создать COM-программы. Только EXE.


        1. axe_chita
          30.11.2022 19:33
          +1

          Все это было вроде с 5 версии.
          Оверлеи были уже со второй версии ТР
          А это с 6 версии. До этого только вставки машинных кодов.
          Но тем не менее в эти inline можно было прямо обращаться к переменным функции, и я видел в каком то переводном печатном учебнике по ТР3, что в inline могли использоваться мнемоники, а не коды операций.
          Единственно чего не позволял турбо паскаль — создать COM-программы. Только EXE.
          Наоборот, только с четвертой версии ТР научился создавать exe файлы. А до этого были только COM


          1. PuerteMuerte
            30.11.2022 20:05

            и я видел в каком то переводном печатном учебнике по ТР3, что в inline могли использоваться мнемоники, а не коды операций.

            Не могли там использоваться мнемоники, но приличной практикой у программистов было писать коды в столбик, а за ними в каждой строке в комментах приписывать мнемонику, потому что наизусть соответствие кодов мнемоникам помнили только самые оторванные черти. Возможно, вы как раз такой пример и видели.


            1. axe_chita
              30.11.2022 21:12

              Нет там именно было без комментариев, прямо в теле inline команды ассемблера разбитые косыми чертами. Я тогда думал, что это не работает у меня из-за того что я пользуюсь устаревшей второй версией ТР под MSX DOS


              1. kuza2000
                30.11.2022 22:29

                Да, было такое. Сам вставлял в код ассемблерные вставки. Правда, не в TP, а в Борланд C++ билдер. Не помню, как команда начиналась, потом открываешь фигурную скобку - и погнали.


                1. PuerteMuerte
                  30.11.2022 22:34
                  +3

                  asm {

                  }

                  Но это совсем уже другая эпоха инструментов разработки. В первых турбопаскалях это выглядело как inline( $F0/$0F/$C7/$C8);

                  И только где-то с шестой версии, кажется, появился аналогичный оператор asm...end, в середине которого можно было писать мнемоники.


        1. axe_chita
          30.11.2022 19:33

          удалено — дубликат


      1. mad_nazgul
        02.12.2022 18:43
        +1

        Проблема в том, что у Turbo Pascal совместимости снизу вверх по TPU не было от слова совсем. Т.е. коммерческие библиотеки нужно было поддерживать сразу для нескольких версий Turbo Pascal.
        В бытность мою студентом, когда работал в лаборатории при кафедре информатики, писали приложение под Turbo Psacal 5.0, т.к. нужная библиотека (коммерческая) была только пол неё.
        В отличии от Turbo C/C++, где можно было подключить любую внешнюю бинарную библиотеку, лишь бы заготовочные (.h) файлы были.


        1. PuerteMuerte
          02.12.2022 23:02

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

          В отличии от Turbo C/C++, где можно было подключить любую внешнюю бинарную библиотеку, лишь бы заготовочные (.h) файлы были.

          В Турбо-Паскале, к слову, так тоже можно было делать без проблем, он хавал тот же формат объектных файлов, что и борландовский С++, но в силу того, что TPU в 1980-х были совершенно имбовой штукой по удобству работы, практически никто компоновку по-сишному не юзал.


  1. baldr
    30.11.2022 10:50
    +1

    Ну, допустим, TASM был опубликован в 1989 году и его уже можно было найти. Но вот редактор TASMED появился уже лет на 6-8 позже, насколько я помню. Быстро нагуглить не удалось, правда.

    Ну и по поводу deLorean - нас откуда куда перенесло-то? 1990 находится вообще в будущем относительно даты оригинального фильма.


  1. kh0
    30.11.2022 10:50
    +12

    План, в принципе рабочий, но можно же круче:
    Если выкинуло в сша:
    1 вариант.
    Идем в Юникс, а затем в Линукс в разработчики c++, и дальше, год от года в течении 30 лет, становмися мегагуру Линукса, параллельно выпуская 100500 книжек по софт-скилам и их важности, а так же о прогрессивных методах разработки. Бабосы вкладываем в "Первые в Мире Международные IT-Галеры", организованные где-нить в восточной Европпе, а кадры высасываем из СССР большим пылесосом: был молодой ученый/математик-краснодеревщик-краснодипломнник/Айтишник - стал прогер на галере после допила. После раскрутки материнской конторы в сша бабло можно брать с "Насдака" за свои же акции и вкладывать их в "сателлит". Можно "на своей галере" пилить гугол или фейсбук, но это трудная дорожка. Это если у вас времени дофига. А если на расслабоне, можно просто копить бабосы до бума доткома и удачно там наварить 5х и вложить все в эппле/гугол/микрософт потом. Можно просто Брина найти и сделать прямую инвестицию.
    2. Вариант.
    Качаться на борланд/микрософт с/с++, ждать прихода винды 3.00 и дальше развиваться по ветке с++ на винде. Либо на дядю пахать, либо пилить какой-нить будущий популярный продукт типа icq, либо игровой проект типа мортал-комбата/дума/кваки/контры на минималках.

    А! главное! Если кому "повезет" найдите тех чуваков, которые якобы настоящие авторы Фейсбука и посоветуйте им гнать в шею рыжего проныру!
    Еще можно попинать чувака из Нетскейпа, чтобы он сразу пилил Тайпскрипт без порнографии.
    Или вот еще можно попытаться попинать толстую ленивую свинью IBM, чтобы они не связывались с рыжим гейтсом и вывели полуось в лидеры.

    Если выкинуло в РФ, срочно хоть тушкой хоть чучелком бежать в сша.
    Кроме ИТ, можно "сочинять" популярные музыкальные хиты, которые вспомнишь. Можно сценарий терминатора 1-2 написать, и даже более того. Если совесть позволяет - можно троль-патентовать. Очень выгодно можно вложить будет в ПайПал в Маска.
    Главное, не лезть в политику и не пытаться изменить особо мир,- просто пробалдеть и сделать по мере сил его чуть-чуть лучше.
    А дальше? А дальше строить супербункер, вы же не знаете, чем закончится "этот карибский кризис 2022". Еще можно попытаться что-нить на минималках с Фукусимой порешать, ну хотя бы утуб-ролик запилить, что японцы-лажовщики, и что у них уровень дизель-генераторов "ниже ватерлинии" и разъемы несовместимые с привозными.

    А ассемблер... Ассемблер это романтично, но полезно ровно в той степени, чтобы помогало в разработке и отладке на с++.


    1. SADKO
      30.11.2022 11:30
      +5

      Нее, вы походу не уловили толщину авторского стёба, тут не в ассемблере дело, а в том что подавляющее число нынешних галеристов, окажись они в девяностых, сосали-бы лапу со всеми своими глубокими знаниями фреймворков ;-)

      Помню, в одной школе, попался старый учитель информатики, реальный программист, на BAISIC. Он был стар и в системное программирование уже не мог, но...
      ...для Агата он запилил текстовый редактор, с векторным шрифтом и многоразличными способами отрисовки оного, причём на экране это всё отображалось условненько, а вот на принтер выходило во всей красе (экран агата так не мог). Тогда только появился лексикон, и самым популярным текстовым редактором был F4 командира Нортона...


      1. sshmakov
        30.11.2022 13:37

        Как назывался редактор, помните? Или фамилия учителя?


        1. PuerteMuerte
          30.11.2022 13:52
          +13

          Судя по описанию, не исключено, что ТеХ и Кнут соответственно :)


      1. xaoc80
        01.12.2022 00:52
        +1

        Полагаю, для современного жителя России, окажись он в 1990 году, вопрос программирования отошел бы на 10-й план и лапу, возможно, пришлось бы сосать в прямом смысле этого слова.


        1. PuerteMuerte
          01.12.2022 01:47
          +8

          лапу, возможно, пришлось бы сосать в прямом смысле этого слова.

          Я помню свои 90-е, это вполне себе сочеталось с программированием. С утреца - на дачу садить помидорчики, поливать помидорчики, опрыскивать помидорчики, собирать жуков с помидорчиков, подвязывать помидорчики, собирать помидорчики. А после обеда за кампухтер. До сих пор ненавижу дачи и помидорчики.


          1. xaoc80
            01.12.2022 09:56
            +2

            Для человека, кто рос в 90-е, как я, например, программирование было нереальным увлечением, другой мир, в который можно было погрузиться и уйти от реальности. О деньгах и перспективах даже не помышлял. Первую полезную программу написал для УКНЦ, Пентиум 1 казался изделием из параллельной вселенной.


        1. addewyd
          02.12.2022 15:00

          Неправда, 1990-2000 в этом отношении самые продуктивные были. Бабло текло рекой, так как железо уже было, а софта не было.
          Потом пришла 1с и монополизировала рынок.
          Да, ещё где-то в те же времена казино закрыли. Эти за софт вообще бешеные деньги готовы были платить. Эхх…


          1. PuerteMuerte
            02.12.2022 17:00
            +2

            Бабло текло рекой

            К кому-то может и текло, а так, на "рынке" тогда было навалом выпускников советских ВУЗов, готовых работать за тарелку макарон (и я, к слову, был один из них), и всё это здорово мешало грести бабло реками, потому что если ты задерёшь цену, клиенты просто наймут другого такого же.


            1. addewyd
              02.12.2022 18:47

              Странно. Эти самые клиенты в глаза не видели тогда персоналок и даже не знали, что можно кого-то нанять. Мы сами приходили и предлагали. Ставили ХТ, принтер и прогу на клиппере в бухгалтерию. Другие увидели такое чудо, и тоже к нам.
              Оставалось ездить по городу и райцентрам и собирать дань за обслуживание и обновления. Налом.

              А кого там выпускали в 90м, хз. Те, с кем я работал, выпускались где-то в середине 70х в основном. Я позже, да, но и вуз у меня непрофильный был.

              С казино вообще в наших краях кроме меня никто не работал, насколько я знаю.
              Увидел как-то у знакомого буха в соседнем казино бд клиентов в экселе, предложил свой вариант. Через год система работала в половине казино города, остальные очень желали приобрести. Не успели… Но это было чуть позже.

              Была ещё мода на мини-АТС. Ставишь в гостиницу, отдельно софтина для тарификации (не было в комплекте).

              Потом всё просто покатилось по наклонной. Да и мелкий бизнес задушили напрочь. Или сам сдох. Даже не представляю, где сейчас можно приткнуться, скажем, команде из 3-5 человек. А в 90е — простор для деятельности. в 00х всякие вебстудии повырастали как грибы. Тоже немногие выжили.


    1. Alexandroppolus
      30.11.2022 11:33
      +1

      Главный вопрос, как и на что жить первое время, да ещё чтобы денег скопить на инвестиции. А так, ближайший к 1990 году мегатрамплин - это ммм94, там при определенной сноровке можно поднять до 100х.


      1. salnicoff
        30.11.2022 11:43
        +2

        В 1990 можно было подняться на наперстках.


    1. SlFed
      30.11.2022 11:36

      Класс. При биткоин только забыли.


      1. acsent1
        30.11.2022 22:20
        +1

        До биткойна еще 18 лет


    1. axe_chita
      30.11.2022 19:52

      Качаться на борланд/микрософт с/с++, ждать прихода винды 3.00 и дальше развиваться по ветке с++ на винде.
      И тут придет VisualBasic, и опошлит все прокаченные скилы С++, с отладкой кода на MDA мониторе. Потому что, по другому тут нельзя. Ибо пока вы отдебажите свой проект на плюсах, конкуренты выпустят два десятка корявеньких, но работающих здесь и сейчас программ под Win3.x
      А ассемблер… Ассемблер это романтично
      Это не романтика, это суровая правда жизни, боль, пот и кровавые слёзы, а иногда единственный инструмент выбрать тот самый «последний дюйм»
      «Эх молодежь!»


    1. boroda230
      30.11.2022 20:12
      +3

      Если выкинуло в 90-м в РФ, перед тем как "бежать в США" до 1995-1996 можно поднять достаточно денег на ремонте и на покупке-продаже любого компьютерного оборудования. Спрос на него и на спецов по железу был колоссален. Ехать и обустраиваться надо же было на что-то.


      1. vassabi
        01.12.2022 18:16

        гланое, чтобы братки не забили стрелу ;)


        1. PuerteMuerte
          01.12.2022 18:56

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


        1. boroda230
          02.12.2022 19:17

          Браткам это не было интересно от слова совсем. Суммы менее 5 штук грина их не возбуждали. Написал все как было у себя. В 92-м, пять сотенных зеленых в кошельке была нормой.


          1. PuerteMuerte
            02.12.2022 22:54
            +1

            Ну, эт повезло просто. Или место такое. Братков, которые стригли мелкий бизнес по принципу "пять бабулек по 20 коп - уже рупь" у нас было навалом.


  1. salnicoff
    30.11.2022 11:29
    +28

    Такое ощущение, что человек не жил в 1990 году, потому что у статьи должно быть два варианта.

    Первый:

    Итак, DeLorean доставил вас в США 1990 года. Идем в магазин, покупаем за те же деньги нормальный настольный компьютер на 486-ом процессоре, который от рождения умеет считать с плавающей точкой, ставим на него третью «Винду» и пишем на Turbo Pascal/C++/бейсике примерно так же, как и сейчас. Ассемблер используем либо для критически с точки зрения скорости мест в коде, либо для вирусов.

    Второй:

    Итак, DeLorean доставил вас в СССР 1990 года.

    Несколько недель бегаем, чтобы обзавестись пропиской в том городе, куда попали, и талонами на еду. Обязательный минимум — водка, табак, сахар, мясо, рыба, яйца, масло сливочное, масло подсолнечное, крупы, макароны. Если попали в Ярославль, не забываем записаться на получение книжки покупателя на 1991 год. Затем начинаем играть в топовый квест 1990 года: отоварь талоны. Чтобы в нем победить, нужно найти магазин с едой, зайти в него 30 ноября с ноябрьскими талонами на мясо, майскими талонами на рыбу и декабрьскими талонами на яйца. Зайти нужно путем стояния очереди, периодически меняя на себе татуировки с номером позиции в этой очереди. Разработчики квеста добавили в него элементы шутера от первого лица, забыв дать игрокам рэйл-ганы и IDDQD, поэтому файтинги будут исключительно рукопашными, с использованием подручных предметов. Не забывайте, что после начала файтинга могут приехать милиционеры и зайти со спины с «демократизаторами» типа «Аргумент».

    Пройдя первые части квеста и поучаствовав в масс-файтинге за еду, нужно заняться дачными вопросами: купить рассаду помидорных кустов, сделать из чего-нибудь коробочки (это отдельный уровень квеста), посадить рассаду в коробочки и заставить ими подоконники. Последнее заменяет жутко модную компьютерную игру 1990 года «Тетрис»: в «Тетрисе» хотя бы фигурки цветные, но после этого уровня нашего квеста вы с легкостью будете различать 100500 оттенков зеленого цвета и делать такие искажения пространства и времени, которые Эйнштейну и не снились.

    После этого у вас должно найтись время для митинга народного фронта за выход из СССР или, если «DeLorean» доставил вас в место, не очень далекое от Москвы, за отмену 6-ой статьи конституции. При попадании в некоторые национальные окраины вам будет предложен бонус-левел: гражданская война на национальной или религиозной почве. Будьте осторожны, на этом левеле у вас будет всего одна жизнь, а IDDQD и IDKFA отключены.

    Успешно пройдя все уровни, вы можете включить телевизор и посмотреть новейшее шоу «Поле чудес», которую ведет бывший журналист «Взгляда» Влад Листьев. В рекламных паузах этого шоу вам покажут рекламу новейших 486-ых компьютеров, которые ввозит в СССР только что созданный кооператив «МММ». А потом, около полуночи, не забудьте выключить свой ламповый телевизор, потому что они любят перегреваться и устраивать пожары. Спокойной ночи! Завтра утром вы должны будете пройти этот квест заново.

    А где же программирование? Нет, блин, после всего этого вы хотите еще и попрограммировать???


    1. slog2
      30.11.2022 16:01
      +8

      Во втором варианте надо бы добавить что каждому гражданину СССР, конституцией гарантировано право на труд, поэтому весь квест надо проходить в свободное от работы время.


      1. PuerteMuerte
        30.11.2022 16:21

        А как же романтика забастовок?


      1. salnicoff
        30.11.2022 21:09

        Во втором варианте граждане СССР в 1990 году дали себе право забивать на работу ради отоваривания талонов, так что квесты можно было проходить и в рабочее время, особенно если работа не была связана с управлением каким-нибудь ядерным реактором.


    1. BeLord
      30.11.2022 18:05
      +2

      На дворе 1989, комп PC Olivetti Prodest PC1, город вдалеке от столиц, CCCР, сидел и программировал на asm и basic, дефицит был конечно, но если навык доставать и крутится был, то все решаемо. Персики и абрикосы летом были настоящие со своего огорода, а в столицах уже запахло беспределом. 1992, уже не СССР, 286 asm C. Правда деньги зарабатывались на продаже ZX Spectrum, пока шахтеры касками стучали.


      1. PuerteMuerte
        30.11.2022 19:33
        +2

        но если навык доставать и крутится был

        Я посмотрел только что, он стоил в то время в Италии порядка 1200000 лир в базовой комплектации, что по тогдашнему курсу около 1000 американских долларов. Совершенно безумная и космическая сумма для советского человека. Так что навыка "доставать и крутиться" явно было недостаточно, в цепочке поставки сего чуда из итальянского магазина на стол советского человека ещё у кого-то должен был быть как минимум навык "отжать" или хотя бы "спереть".


      1. salnicoff
        30.11.2022 21:10

        Персики и абрикосы летом были настоящие со своего огорода

        У нас с этим проблемы были, и тогда, и сейчас...


    1. axe_chita
      30.11.2022 20:56
      +3

      Первый:

      Итак, DeLorean доставил вас в США 1990 года. Идем в магазин, покупаем за те же деньги нормальный настольный компьютер на 486-ом процессоре, который от рождения умеет считать с плавающей точкой, ставим на него третью «Винду» и пишем на Turbo Pascal/C++/бейсике примерно так же, как и сейчас. Ассемблер используем либо для критически с точки зрения скорости мест в коде, либо для вирусов.
      «Фантазёр, а мы с тобою не пара»
      Нельзя так просто взять и купить 486 комп в США 1990 года, и ваш осётр урезается до:
      386sx@16/1mb/fdd1,2 & 1.44mb/40mb/SVGA800x600x16 цветов одновременно за сущие 1099.99$ без монитора. А если вы у нас купите «SVGA» монитор 14 дюймов с 0,39 dot pinch (кто знает в чем подвох молчите) за жалкие 329.99$, то мы сделаем скидку на системник в сто (100) баксов и но вам обойдется в 999.99$. И это еще оптимальный вариант, IBM PS/1 на 286 в базовой конфигурации вам обойдется в 1589.99$
      Кстати, в октябре 1989 года в NY Times писал о 486 «NCR is among several companies that have already announced they are in the race to sell the first 80486-based systems. For prices expected to be $10,000 to $20,000»
      Спортивный альманах вы ещё не выкинули? ;) Может пора делать ставки Биф?


  1. saag
    30.11.2022 11:47
    +1

    А что чуть что так ассемблер, в 80-е вполне себе бухгалтерия используя Basic на Wang'e и на его импортозаместительном аналоге Искра-226 работала, Fortran также использовали, ну это уже на больших машинах. А в 90-м, если годик подождать так в 91-м так и HTML появится, вот вам и день рождения фронтэнда. Кстати, а почему в 90-й год? Почему бы не в 80-й, вы попадаете туда, идете ТУ(техническое училище) где готовят телемастеров, набираетесь практиса и денег на левых заказах, во второй половине 80-х начинаете собирать Спектрумы, продаете их по демпинговой цене в 800 рублей,осваиваете Basic, пишете игры, продаете их, становитесь кооператором в кожаном пиджаке, потом 90-е и понеслось HTML, Perl, Java...


    1. K0styan
      30.11.2022 13:18
      +1

      Фронтенд в 1991-м, конечно, появится, но пока только на уровне академической игрушки. А вот с 96-97 можно первую волну коммерческой разработки страничек поймать.


  1. Kotofay
    30.11.2022 13:03
    +8

    Главное при попадании в 1990-е годы США, не забыть "спортивный альманах 2000".


    1. Alexandroppolus
      30.11.2022 18:39

      Интересно, кстати, с каким коэффициентом можно было бы весной 92 года поставить на победу Дании в ЧЕ-92


    1. GvrKonstantin
      30.11.2022 18:41

      Не надо нам Альманаха ... или вы хотите третью серию ?


  1. KarmaCraft
    30.11.2022 13:11
    +1

    В 1990 году приходилось знать как минимум три вида ассемблера. Есть сферы где без ассемблера никуда и сегодня. Да что там сегодня, прямо сейчас ...


    1. perfect_genius
      30.11.2022 21:19

      А сейчас где, кроме микроконтроллеров и изучения вирусов?


      1. salnicoff
        30.11.2022 21:22
        +1

        Драйвера, например. Криптография. Какие-то специальные вычисления.


      1. YuriPanchul
        30.11.2022 21:48

        Вот вы включаете ваш настольный компьютер. Процессор проходит reset sequence и выставляет на шину адрес, чтобы выбрать первую инструкцию из памяти. Что это за инструкция? Варианты:

        1. Это часть программы, скомпилированной с питона

        2. Это часть программы на ассемблере, написанной лично Биллом Гейтсом в 1978 году, и с тех пор к ней никто не прикасался.

        3. Это магический код вселенной, который поместил в память компьютера святой дух.


        1. PuerteMuerte
          30.11.2022 22:47

          Варианты

          Все три неверные ;) Первая инструкция там - кусок бутблока BIOSа, которая написана скорее всего на C, лет на 30 позже Билла Гейтса (который, к слову, загрузчики BIOSа и не писал никогда). Ну ладно, может быть, один-единственный джамп с FFF0 на основную точку входа в бутблок там в сурцах действительно прописан в виде ассемблерной команды, хотя тоже не факт.


          1. YuriPanchul
            30.11.2022 23:09

            А вам не приходит в голову, что делать джамп прямо из reset vector в функцию написанную на си не получится например потому что сишная функция ожидает уже подготовленный указатель стека? Или вы думаете, что указатель стека сразу будет стоять правильно в момент сброса на всех процессорах, и x86, и Apple ARM-based, и новомодных линуксных ноутбуках с RISC-V?


            1. PuerteMuerte
              01.12.2022 00:09

              Нет, но ведь бутблок - как раз та часть биоса, которая ни разу не кросс-платформенная. В старых х86 начальное значение стека не детерминировано, как сейчас, хз, не интересовался. В армах оно предопределено, но в любом случае, если вы современный разработчик биосов, вы про это не будете думать, это на себя возьмёт тулсет, с помощью которого вы образ биоса собираете.


              1. YuriPanchul
                01.12.2022 03:05

                А тулсеты на деревьях растут? Или разработчикам тулсетов ассемблер знать тоже не нужно? За него код на ассемблере AI напишет? Разработчику надо только на питоне написать AI который сам прочитает интеловский мануал и внесёт в свою нейросеть знание ассемблера?

                Короче, я только что позвонил своему приятелю Алексу Белицу, который видел биос от Финикса в исходниках в 2012 году. Его компания работала с финиксом Говорит что почти все на ассемблере, только небольшой кусок сетапа на си. Можете его найти на Фейсбуке Alex Belits и распросить прямо.


                1. thevlad
                  01.12.2022 03:27
                  +1

                  В legacy bios-ах очень долго тянули всякий мусор, в uefi биосах почти все было переписано на C. (мне IDA рассказала)


                  1. YDR
                    01.12.2022 08:52

                    ИДЕ можно верить, она знает. Но предполагаю, первые команды настройки сегментных регистров, стека, контроллера памяти, все равно должны быть на ассемблере. Вот в защищенный режим не знаю, где современные системы переходят. Помню, друг писал свой (аналог dos4gw/cwsdpmi/dpmiinst?). Из доса сначала в защищенный, а потом туда-сюда гонял, чтобы прерывания реального режима выполнить, и вернуться в защищенный. С отладкой были проблемы... Если зависало, отправлял FF в порт 20 и смотрел, когда начинало перезагружаться. Если перезагружалось - то вставлял FA F4.

                    Даже в обычной программе есть что-то, что выполняется до main(). для х86 давно не смотрел, но для Cortex M3 (CMSIS?) там все очень похоже на нативный ассемблеровский код.


                    1. thevlad
                      01.12.2022 10:23

                      Это естественно, но по сравнению с legacy bios ассемблерного кода было на порядок меньше.


            1. thevlad
              01.12.2022 03:17
              +1

              Прикол, что там еще и контроллер памяти не инициализирован. В современных железках есть режим CAR(cache as ram). А раньше был код на регистрах, либо специальный компилятор. Но вообще в современных биосах (начиная с UEFI) ассемблера очень мало.


      1. kuza2000
        30.11.2022 22:52
        +3

        Не знаю как сейчас с этим делом обстоит, но когда в те годы программировал в C++ билдере, то знание ассемблера выручало. Неоднократно ловил билдер на ошибках компиляции, заглядывая в ассемблер.
        Выглядит это так. Все отлажено и работает в дебаг версии. Компилируешь релизную с оптимизациями - не работает. Начинаешь отлаживать, находишь место, где происходит что-то очень странное. Заглядываешь в код на ассемблере - а там фигня. Скомпилировано совсем не то, что написано. Переписываешь пару строк по другому - и взлетает. Причем без оптимизаций компилирует нормальный код.


        1. 0xd34df00d
          30.11.2022 23:21
          +8

          Что-то мне подсказывает, что это были не ошибки компиляции, а UB.


      1. 0xd34df00d
        30.11.2022 23:20
        +4

        Полезно при написании вычислительного кода даже на более высокоуровневых языках, чтобы посмотреть, что там компилятор сгенерировал.


        Интринсики — этакий ассемблер-лайт на минималках — полезны, когда компилятор таки не осиливает сгенерировать нормальный код, а совсем по хардкору заморачиваться вещами вроде распределения регистров неохота.


      1. dikansky
        01.12.2022 09:30

        Это удивительно, но мэйнфреймы в Техасе, на которых ПО Sabre обсчитывало данные для Аэрофлота, требовали поддержки разработчика на ассемблере... ещё в начале этого года.


  1. KongEnGe
    30.11.2022 17:04
    +3

    У вас нет ассамблера в магазине? Что ж, возможно, придется нащелкать его с пульта программатора (вспоминая журнал "Радио" второй половины 80-х)


    1. kuza2000
      30.11.2022 22:39

      Ничего страшного, нащелкаем, там всего два кило))


      1. KongEnGe
        01.12.2022 00:02
        +1

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


      1. YDR
        01.12.2022 08:56
        +1

        нет, с программатора тумблерами - "Монитор". Дальше можно в кодах набирать. """

        М 8000

        8000> 3E 00 21 00 80 CD 06 F8 3E 20 ...""" или типа того.

        тумблеры < коды < ассемблер < С < ...


  1. YuriPanchul
    30.11.2022 19:38
    +2

    *** Как программист из 2022-го вы сталкивались с ассемблером разве что на лабораторных работах в университете. ***

    Понятно, вы считаете, что компиляторы, ядра операционных систем и низкоуровневые библиотеки то ли растут на деревьях, то ли их все написали 30 лет назад (кстати тогда говорили "ассемблер использовали только в 1960-е годы").

    Я даже не говорю про разработчиков микропроцессоров (представляете, такие есть даже в России - Syntacore, НИИСИ, НПЦ Элвис и другие) для которых ассемблер нужен для написания процессорных стестов и вообще своего рода архитектурный API к их микроархитектурным реализациям.


    1. PuerteMuerte
      30.11.2022 20:01

      Справедливости ради, ни компиляторы, ни ядра операционных систем, ни низкоуровневые библиотеки на ассемблере уже давным-давно не пишут, по крайней мере, в промышленной разработке. Это и слишком долго, и слишком дорого, и предъявляет повышенные требования к разработчикам и к контролю качества. Естественно, бывают энтузиасты, у которых есть подобные пет-проекты, но погоды они не делают. Единственное применение ассемблера, в которое попасть шансы не нулевые - это embedded-разработка, и то, даже там чаще вы будете с чем-то более высокоуровневым сталкиваться.


      1. YuriPanchul
        30.11.2022 20:44
        +1

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

        Далее, я в курсе, что даже самые малые RTOS-ы в основном пишутся на Си. Но как вы обойдетесь без знания ассемблера в обработчике прерывания, в котором нужно сохранять или переключать регистровый контекст, запрещать другие прерывания и переходить, если нужно в "большой" обработчик на Си?

        Насчет библиотек: когда вы пишете оптимизированную библиотеку скажем для матричного умножения в AI, которая использует векторные регистры, вам тоже не нужен ассемблер? Вы думаете компилятор понимает все о векторизации и конкретном поведении конвейера конкретного процессорного ядра в таких случаях.


        1. 0xd34df00d
          30.11.2022 23:22
          +1

          Насчет библиотек: когда вы пишете оптимизированную библиотеку скажем для матричного умножения в AI, которая использует векторные регистры, вам тоже не нужен ассемблер? Вы думаете компилятор понимает все о векторизации и конкретном поведении конвейера конкретного процессорного ядра в таких случаях.

          Технически ассемблер для этого действительно не нужен.


          1. YuriPanchul
            30.11.2022 23:33
            +1

            Я работал в MIPS Technologies и лично наблюдал, как человек писал в 2019 году оптимизированную последовательность ассемблерных инструкций для быстрого выполнения AI функций с помощью векторного расширения процессорных ядер MIPS P5600 и MIPS I6500 (первое используется в процессоре Байкал-Т, второе лицензировано японской компанией denso для автомобильной электроники).

            Вы также можете писать си-функцию с ассемблерными вставками, но это тоже ассемблер.


            1. 0xd34df00d
              01.12.2022 20:03
              +2

              Из того, что кто-то что-то делал через ассемблер, не следует, что это обязательно надо делать через ассемблер.


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


              • отсутствие интринсиков для недавно появившихся инструкций (ничего, добавят в следующей версии компилятора), и
              • неудовлетворённость аллокатором регистров, выбранной кодировкой (ну там, VEX, EVEX, это всё), и так далее (настолько редко, что можно пренебречь).


              1. YuriPanchul
                01.12.2022 20:14
                +1

                *** отсутствие интринсиков для недавно появившихся инструкций (ничего, добавят в следующей версии компилятора), и ***

                Вы все правильно говорите, и вот как раз в 10 метрах от товарища, который писал эту последовательность инструкций - сидел другой товарищ, который добавлял интринсики в компиляторы GCC и LLVM, а еще на некотором расстоянии от них сидел архитектор, который придумывал новые инструкции, и целая куча народу (включая меня) которая эта инструкции реализовывала в RTL и верифицировала.

                То есть это не некое обезличенное "добавят", а конкретные люди, и всем этим людям нужно знать ассемблер, а не только "видеть его на лабах в институте".


                1. 0xd34df00d
                  01.12.2022 20:22

                  Ну, тогда эту задачу логичнее называть не «написание оптимизированной библиотеки для матана», а «добавление обёрток вокруг ассемблерных инструкций в компилятор [возможно, на примере]» или «добавление новых инструкций в процессор на основе опыта решения модельных практических задач».


                  Если я пойду и начну писать «оптимизированную библиотеку для матричного умножения» под x86, то интринсиков мне хватит.


        1. easyJet
          01.12.2022 08:53
          +3

          В компиляторах еще есть встроенные функции для работы с векторными расширениями, например _mm256_add_ps в intel c++ compiler, не говоря уже от куче врапперов и мат. библиотек доступных для любого ЯВУ, многие из которых еще и могут перенести расчеты на видеокарту.

          В ОСРВ действительно единственное место где нужен асм это сохранение/восстановление контекста и переключение стеков, в остальном работа с памятью и периферией на си.


          1. YuriPanchul
            01.12.2022 09:22

            Это все понятно, но ведь врапперы и встроенные функции же не на деревьях ростут, их пишут конкретные люди в конкретных корпорациях (в том же интеле) за зарплату. И если вы один из них - вам нужно знать ассемблер. Таких людей на самом деле не так уж и мало - отдел software stacks в любой процессорной, SoCб DSP итд компании.

            В ОСРВ это не единственное место. Есть еще boot, в котором нужно поставить стек, инициализировать кэши и устравление виртуальной памятью (фиксированный MMU есть даже в микроконтроллерах), поставить конфигурацию контроллера прерываний и только потом перейти на сишную программу. Пример такой минимальной последовательности см. напр. (беру первый попавшийся из мне известных) https://github.com/MIPSfpga/mipsfpga-plus/blob/master/programs/03_cache_misses/boot.S

            В RTOS которые поддерживают аппаратную многопоточность, например ThreadX, есть и другие места, где нужны ассемблерные вставки для определенных процессоров, чторбы работать с этой многопоточностью. Они тоже wrapped в макросах, но они есть.


  1. YuriPanchul
    30.11.2022 21:41
    +1

    Я просмотрел пост снова и понял, что автор либо гонит пургу чтобы потролить народ, либо имеет о 1990 годе совершенно фантастическое представление типа того, что при Сталине жил Пушкин.

    В 1990 году у x86 компьютеров повсеместно были хард драйвы. Небольшие 20-60 mb но хард. Встретить 8088 с двумя флопиками A и B это было ну как сейчас встретить на дороге Шевроле 1975 года. X86 с двумя флопиками были в самом начале, в 1980 году, но их быстро вытеснили компьютеры с хард драйвами (сначала xt, потом at).

    В смысле ассемблера 1990 год вообще не отличался от 2022, ни на йоту. Никто в 1990 году не использовал ассемблер для писания прикладных программ. Прикладные программы на ассемблере (например для бухгалтерии в штатах и для всяких расчетов) писали в 1960 году, на 30 лет раньше, хотя уже тогда переходили на Фортран, алгол и Кобол.

    В 1990 году, как и сейчас, ассемблер использовали для:

    1. Части кода драйверов

    2. Ассемблер нужно было знать разработчику бэкэнда компилятора

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

    4. Обработчики прерываний и boot последовательности в операционных системах

    5. Вообще, точно так же как и сейчас, для таких задач использовали смесь ассемблера и Си. Переход на Си с языков типа Паскаля произошел с примерно 1980 года до 1985.


    1. shiru8bit
      01.12.2022 04:08
      +2

      Игры для разнообразных 8-16-битных игровых платформ в 1990 и до примерно 1995 ещё довольно активно писали на ассемблере. На C произошёл массовый переход только с приходом 32-битных платформ.


      1. YuriPanchul
        01.12.2022 04:55

        Это не совсем так. Насколько я помню (хотя могу ошибаться) игры от компании Konami на компьютерах MSX Yamaha с 8-битным процессором Z80 уже с 1985 года писали на смеси C (компилятор ASCII C) и ассемблера.


        1. shiru8bit
          01.12.2022 05:13
          +1

          Процент написанных на C игр года игр для приставок и домашних компьютеров тех лет, особенно для 8-битных, очень мал. И он в основном сосредоточен на платформе PC/MS-DOS, где память и скорость не были так сильно ограничены (компилированный код в несколько раз больше, не говоря про скорость, это большая проблема на 8-битных платформах).

          Про Konami я подобное слышу впервые и очень сильно сомневаюсь. Похожие слухи ходили про игры KOEI на Famicom, но и там это только на уровне догадок, потому что код выглядит странно. Пока все игры, исходники которых открывались авторами, были написаны на ассемблере.


          1. YuriPanchul
            01.12.2022 06:45

            Я не буду особенно спорить по поводу Konami, но хочу уточнить вашу фразу "компилированный код в несколько раз больше, не говоря про скорость". Вы имеете в виду неоптимизирующие компиляторы на 8-битных машинах? Потому что кросс-компиляторы того времени (например основанные на PCC - Portable C Compiler) уже оптимизировали неплохо, умели размещать переменные на регистрах, а не только в стеке и памяти, использовали числа Сети-Ульмана для аллокаций регистров и оптимального вычисления выражений, и в результате код был не "в несколько раз больше". Современные же (2022) компиляторы для ARM и RISC-V с уровнем оптимизации -O2 могут сгенерить год лучше, чем придет в голову большинству человеческих ассамблерописателей.

            Для MSX Yamaha в 1980-е было минимум три Си-компилятора (Aztec C, BDS C и ASCII MSX-C), первые два действительно генерили плохой код, а вот последний получше


            1. shiru8bit
              01.12.2022 06:53
              +1

              Я имею в виду современные кросс-компиляторы для старых 8-битных процессоров. Размер скомпилированного кода для процессоров уровня 6502 и Z80 очень сильно больше, чем можно написать руками, и это представляет большую проблему в условиях ограниченной памяти и страничной адресации. Современные компиляторы для ARM и RISC-V никакого отношения к этому не имеют, для старых процессоров подобных сверх-эффективных компиляторов нет и быть не может, в виду особенностей их архитектуры.


              1. YuriPanchul
                01.12.2022 07:18

                Ну насчет "быть не может принципиально" - это имхо не факт. Я думаю, что если вбить в компилятор много распознования шаблонов, а также глобальный анализ иерархии вызовов и control flow, то можно заоптимизировать сильно, но другое дело, что делать это сейчас профессиональным компиляторщикам для старых 6502 и Z80 нет вообще никакой мотивации, а для хоббистов это слишком много изучения специализированных алгоритмов и их реализации.

                По сути, принципиальная разница в том, что 6502 - типичная аккумуляторная архитектура, Z80 - расширение аккумуляторной архитектуры с разнофункциональными регистрами, а ARM и RISC-V - это register-rich RISC архитектура. Плюс системы адресации и всякий изврат в Z80 типа (hl), который можно покрыть шаблонами.

                Вы можете привести пример двух последовательностей - скомпилированной и ручной чтобы я понял какие случаи вы имеете в виду (я ассемблер Z80 еще помню, а про 6502 догадаюсь)?


                1. shiru8bit
                  01.12.2022 07:45
                  +2

                  6502 определённо не типичная аккумуляторная архитектура, она вообще мало на что похожа (на прото-RISC, всего 53 инструкции) - большую часть кода занимают явные обращения к памяти. Т.е. если на Z80 что-то загрузил в регистры, можно некоторое время выполнять алгоритм чисто в регистрах, и следующее обращение к памяти будет уже записью результата. На 6502 же постоянно делаются операции с памятью, вплоть до inc addr и сразу же lda тот же addr, чтобы сделать сравнение, не достиг ли счётчик нужного значения, а в целом в коде значения в регистрах задерживаются очень ненадолго.

                  ARM и RISC-V изначально делались с прицелом на компиляторы ЯВУ, а не на ручное написание кода. У 6502 и Z80 среди опкодов нет примитивов, необходимых для эффективной компиляции кода с ЯВУ, и вместо одного опкода там то и дело надо десяток. И у них нет даже элементарных операций целочисленного умножения-деления, так что для эффективности приходится вставлять шаблонные процедуры умножения-деления на константу, наиболее оптимальным для конкретной константы кодом.

                  Нет, готовых примеров у меня под рукой нет, и заниматься их целенаправленным созданием мне не очень интересно.


              1. axe_chita
                01.12.2022 10:21

                Размер скомпилированного кода для процессоров уровня 6502 и Z80 очень сильно больше, чем можно написать руками
                Не всё так плохо, к примеру энтузиасты на этом форуме вполне успешно пилят оптимизатор Ассемблера Z80.
                Да и Hitech C, для Zilog Z80, до сих пор выдает не плохие результаты.


                1. shiru8bit
                  01.12.2022 10:49

                  Энтузиасты настолько успешно запилили оптимизации в SDCC для Z80, что им уже очень давно стало просто невозможно пользоваться, и немало проектов загнулось.

                  'Неплохие результаты' никак не противоречат тому, что код получается сильно неоптимальным, и прежде всего неоптимальным по размеру. Да, компиляторами C можно пользоваться на 8-битках. Я сам приложил усилия к демонстрации этого, и это привело к появлению сотни-другой игр для NES, написанных на C, а Mojon Twins ещё раньше популяризировали то же самое для ZX Spectrum, и там счёт игр ещё больше. Но практика демонстрирует, что нехватка памяти становится очень существенной проблемой, даже более существенной, чем потеря в производительности.


                  1. pharo
                    01.12.2022 13:49
                    +1

                    Для экономии размера кода при сохранении неплохой производительности есть Форт (Forth) реализации и для Z80 и 6502.

                    P.S. Для 6502 пилят CC64 (Си компилятор) в рамках использования Форт, как языка разработки компилятора.



                  1. axe_chita
                    01.12.2022 13:54

                    Энтузиасты настолько успешно запилили оптимизации в SDCC для Z80, что им уже очень давно стало просто невозможно пользоваться, и немало проектов загнулось.
                    Не знаю, SDCC последний раз пользовался лет десять-двенадцать назад.
                    Надо посмотреть как он работает в 8bitworkshop IDE
                    'Неплохие результаты' никак не противоречат тому, что код получается сильно неоптимальным, и прежде всего неоптимальным по размеру.
                    Дело в том что я вам привёл ссылку на программу которая оптимизирует именно Ассемблер, неважно сгенерирован он компилятором или написан руками.
                    Да, компиляторами C можно пользоваться на 8-битках.
                    И можно и нужно. Хотя бы в целях прототипирования и отладки внутренней логики.
                    Я сам приложил усилия к демонстрации этого, и это привело к появлению сотни-другой игр для NES, написанных на C,
                    А сколько бы их было, если бы вы ограничились только Ассемблером?
                    а Mojon Twins ещё раньше популяризировали то же самое для ZX Spectrum,
                    Вот Спектрум, в свете нативной разработки на самой платформе, пардон муа никакашка. Си можно пользоваться только при кросс-разработке, ЧТМ запустить вариант усеченного Small или RAT Си, и скомпилировать «Hello World!», но всё что крупнее будет превращаться в боль
                    Но практика демонстрирует, что нехватка памяти становится очень существенной проблемой, даже более существенной, чем потеря в производительности.
                    Памяти много не бывает;)
                    Тем более, если писать «неоптимально», то на реализацию игры «крестики/нолики» может и 16гб не хватить:)


        1. axe_chita
          01.12.2022 09:29
          +1

          За Konami не скажу, но Андрей Родионов писал свои игры (Майор Пистолетов, Возвращение на Землю, Танцероид) и программы для их создания с использованием BDS С и Ассемблера.


      1. axe_chita
        01.12.2022 09:06

        На C произошёл массовый переход только с приходом 32-битных платформ.
        Не совсем правильно, массовый переход на Си произошел с появлением доступных компиляторов Си. Для 8080/z80 это был BDS C, который доказал, если я не ошибаюсь, саму возможность создания компилятора Си на 8 разрядном процессоре.
        А с 16 разрядными 68000 (да я знаю регистры были 32 разрядные, но АЛУ то могло обрабатывать только 16 бит), всё было еще проще, Си существовал изначально и активно использовался при создании софта.


        1. shiru8bit
          01.12.2022 10:55

          С приходом 32-битных платформ стало нормой иметь из коробки SDK от платформодержателя, и эти SDK для 3DO и PS1 изначально подразумевали разработку на C/C++, с компилятором и библиотеками. Для 8-16 битных платформ официальных SDK просто не было, а 99% самопальных сред разработки и решений от третьих лиц использовали ассемблер. И нет, компиляторы C для 68000 при создании игр для той же Амиги (до середины 90-х), Atari ST или Sega Megadrive активно не использовались. Большинство игр для этих платформ написано на ассемблере, хотя компиляторы C стали доступны достаточно рано.


          1. axe_chita
            01.12.2022 12:48

            С приходом 32-битных платформ
            Вы имели ввиду приставок?
            нормой иметь из коробки SDK
            Ассоциация MSX изначально давала возможность ознакомиться с MSX Red Book и MSX Technical Data Book описывающих стандарт MSX, а после выхода стандарта MSX2 стала доступна MSX2 Technical Handbook. А инструменты для разработки, были доступны ранее в СР/М (microsoft m80/l80 и так далее)
            от платформодержателя
            А платформодержатель это кто?
            и эти SDK для 3DO и PS1 изначально подразумевали разработку на C/C++, с компилятором и библиотеками.
            приставки != ПК, на приставках нельзя осуществлять разработку внутри платформы. Только кросскомпиляция и отладка.
            Для 8-16 битных платформ официальных SDK просто не было, а 99% самопальных сред разработки и решений от третьих лиц использовали ассемблер.
            А использование ассемблера это уже табу?
            C compiler for CP/M - there are a lot of them ...
            Here are the C compiler as complete packages:
            Arnor C 1.00 (no math lib, originally for Amstrad CPCs)
            ASCII C 1.1 (for MSX-DOS, which is almost CP/M compatible)
            Aztec C 1.06d
            BDS-C 1.6 & 2.0 (complete package for CP/M + ZCPR3)
            Ecosoft C Compiler 3.43 (Z80; thanks to Rolf Harrmann !)
            HiTech C 3.09 (Z80. locally mirrored) and a manual for it (locally mirrored)
            HiSoft C 1.35
            ManxC 1.05
            Mi-C 3.18
            Mix C Compiler 2.0

            Mix C Compiler 2.1 — see Bill Buckels web pages
            Q/C Compiler V3.1a (Z80, Codeworks aka Quality Computer Systems)
            SIL 1.5 from Digilog (with a subset of C, but with some other extensions)
            Small C 2.1 (no float, partly K & R, source exists here)
            Small C 2.7 (created by F. A. Scacchitti in Oct. 1986)
            Small C 1.2 with floats (Z80, SIG/M 224)
            Small C/Plus with floats and structs/unions (v1.0, 1988)
            Another Small C variant named MESCC with code optimizations from Miguel I. García López can be found at his webpage, an old local mirror is here (he has also a Github page with a current version)
            Supersoft C 1.3 (not sure all needed files are included, plz feedback)
            Whitesmith C 2.0 (seems complete)
            Whitesmith C 2.1 (now also complete !)

            И нет, компиляторы C для 68000 при создании игр для той же Амиги (до середины 90-х), Atari ST
            Это надо смотреть по текстам ошибок рунтайма в бинарниках.
            или Sega Megadrive активно не использовались.
            А вот тут вы ошибаетесь, кроссразработка приложения на приставку удобна именно на ЯВУ.
            Большинство игр для этих платформ написано на ассемблере,
            Пока игры были относительно небольшими, и не сложными. И плюс были эксклюзивами только для этой платформы. Как только требовалось закрыть несколько платформ, язык Си, а с ним и Паскаль становились предпочтительнее, так это существенно ускоряло перенос программ и игр.
            хотя компиляторы C стали доступны достаточно рано.
            Быть доступным, и быть удобным для работы — это две больших разницы.


            1. shiru8bit
              01.12.2022 13:24

              А вот тут вы ошибаетесь, кроссразработка приложения на приставку удобна именно на ЯВУ.

              Теоретическое удобство разработки и фактически существующие игры - это две больших разницы.


              1. axe_chita
                01.12.2022 14:55

                Microprose и иже с ними с укоризной смотрят на вас. Оказывается они пользовались чисто «теоретическим» удобством в своём бизнесе.


    1. teplolub
      01.12.2022 09:01
      +1

      Про 1990-й год не скажу, но уже в 1991-ом в не самом крутом ВУЗе Москвы - МАСИ - вовсю использовались 286AT/XT для обучения студентов. Писали программы на Фортране, на встроенном языке Автокада (мышки были еще редкостью, чертили командами с клавиатуры). В 1992 году мне был выделен "личный" 286-й с частотой 20 МГц, оперативой 1 МБ и жестким диском 20 Мб. В составе MS-DOS был QBasic с примерами программ.
      В 1989 вышел мой любимый Clarion Database Developer. Уже были Clipper и FoxPro, не говоря уже о Pascal и С. Так что выбор языков и сред программирования в 1990 году был вполне богат.


  1. YuriPanchul
    30.11.2022 21:58

    Про микроконтроллеры автор тоже ничего не понимает или сознательно троллит чтобы вызвать комменты микроконтроллерщиков. Все эти stm32, pic32, AVR и прочие программируются в основном на си, хотя ассемблер разумеется возникает в boot sequence, обработке прерываний и вставках __ asm. Чисто на ассемблере было принято программировать микроконтроллеры а-ля 8051 давно.

    Вот цитата автора, троллит людей словом "обычно":

    "Большое направление программирования на ассемблере – это написание программ для микроконтроллеров. У этих девайсов обычно большие ограничения по мощности процессора и объёму памяти, так что в этом случае ассемблер – это не альтернатива, а единственное средство решения задачи."


    1. YDR
      01.12.2022 09:08

      в 1990 и были только MCS51. про PIC стало широко известно где-то в середине 90х, AVR к концу 90х.. STM32 были еще позже.

      А в 512б...2 кб памяти программ для микроконтроллера сильно не разгуляешься, так что ассемблер.


      1. pharo
        01.12.2022 13:59

        В России тоже был сделан вариант «PIC» контроллера КР1878ВЕ1 к 2000г. но со своими особенностями и вот на нём, действительно, программы делались на Ассемблере в силу небольшого размера объёма для кода программ (1K слов команд)


  1. ovn83
    30.11.2022 22:58
    +1

    В 90м году в СССР любой умеющий держать паяльник мог за среднюю зарплату собрать Спектрум, там Бэйсик прошит. Можно в игры играть и т.п. Устроившись в госконтору можно было кодить на Паскаль на IBM PC, вспоминаем Турбо Паскаль. В те годы набирал обороты Си и Си++. Так что статья мура, а на Ассемблере под ARM коллеги что-то писали сегодня.


  1. shiru8bit
    01.12.2022 04:10
    +7

    Не знаю, что за демонизация сложности ассемблера такая, но в 1990 12-13 летние пацаны осваивали его и без интернета, и без stack overflow, и без хорошо написанных книг, на тех компьютерах или их подобиях, до которых удавалось дотянуться. Это в разное время происходило во всех странах.


    1. LorHobbit
      01.12.2022 04:47
      +1

      Именно! Кому интересно было - осваивали...


    1. salnicoff
      01.12.2022 10:12

      Поддержу. Я выпускную работу в школе на ассемблере (x86+DOS) писал. Сложного нет, просто нужно понять архитектуру железа. Но это все-таки был выпендреж (смотрите, как я могу), если бы я ту софтину писал «на продажу» или «на заказ», то писал бы на чем-нибудь высокоуровневом, ибо прерывание 21h запоминается на всю жизнь, а вот что там в регистрах — это надо каждый раз исходник со справочником смотреть...


  1. LorHobbit
    01.12.2022 04:46
    +1

    Ноутбук, конечно, мажорский.

    Я в 1990-м как раз программировал на ассемблере... КР580ВМ80А, у меня был "Партнёр 01.01" (семейство РК-86, но ОЗУ и ПЗУ было побольше). По умолчанию, как и во всех РК-86-подобных, был шрифт на основе КОИ-7, с заглавными русскими и латинскими буквами. Но в ПЗУ в виде двух половинок была прошита ISO 8859-5, она же "основная кодировка ГОСТ", и я бился над тем, как эти половинки сопрячь вместе. У видеочипа ВГ75 был служебный невидимый байт, позволявший после его размещения в памяти переключаться на другой шрифт, и в зависимости от режима он мог либо занимать знакоместо на экране (выглядеть пробелом), либо не занимать (но в этом случае терялось однозначное соответствие между адресом в памяти и ячейкой на экране). Каким-то чудом я заставил второй вариант работать, написал улучшенный драйвер клавиатуры-экрана и даже выдвигал его на местный конкурс партнёрщиков. Правда, системную программу притащил я один, остальные игрушки демонстрировали.

    Ассемблер-транслятор и редактор, к счастью, были в ПЗУ, но вот текст своего кода приходилось грузить с магнитофона и на него же записывать. Отредактировал, записал, оттранслировал, всё зависло - грузим с магнитофона по новой и думаем, где ошибка. Ни флопиков, ни тем более хардов. Контроллер дисковода, правда, потом в продаже появился, но это было потом, да и дисковод для студента-третьекурсника стоил, мягко говоря, существенную сумму...

    Весело было, короче.


  1. Ontaelio
    01.12.2022 06:30

    Такое ощущение, что ассемблер - какая-то окаменелость, а не низкоуровневый язык программирования. Кстати, в 90-м он считался "среднеуровневым", т.к. были еще машинные коды. Но в любом случае: на чем, по мнению автора, сейчас программируют чипы? Для чего в даташитах пишут asm команды?

    А так в 90-м на дискете надо было иметь турбо паскаль, а ассемблер включать только инлайном для резидентов и прочего шаманства с регистрами и прерываниями.


    1. YuriPanchul
      01.12.2022 07:03
      +3

      Машинный код после 1960-го года использовали только в программируемых калькуляторах, учебнике МГУ 1970-х и в брошуре серии "Популярные лекции по математике". В 1990-м ассемблер был однозначно низкоуровневым языком программирования, как и в 1970-м.

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

      Что касается вопроса "на чем программируют чипы?" то он несколько глубже, чем ассемблер. Посколько с голыми чипами есть два уровня - архитектуры, системы команд (на этом уровне работает ассемблер) и микроархитектуры, устройства железа процессора - стадии конвейера, устройство арифметических блоков, структура кэшей итд.

      И вот для второго уровня есть языки описания аппаратуры - Verilog, SystemVerilog и VHDL, на которых описывается структура процессора и этот код с помощью технологии логического синтеза превращается не просто в "машинный код" (в машинный код превращается ассемблер), а в файл геометрических фигур (GDSII) по которому выпекают чипы на фабрике. То есть это код превращается в транзисторы и дорожки. Вот сравните:

      После чего все вместе работает так:


      1. Ontaelio
        01.12.2022 21:27

        Вот бы это в виде статьи увидеть, особенно про плисы (я не шучу).

        Я по книжкам в начале 90-х помню, что там ассемблер называли "человекочитаемыми машинными кодами" и потому он был "среднего уровня". Возможно, они уже тогда устарели, но вроде там речь шла о 286, и показывалось, как из ASM сделать машинные команды (хотя лично у меня не было возможности это проверить, только инлайн). Ведь там по сути они и есть - буковки заменяют циферки. НО! можно читать и писать по-человечкски.


      1. Brak0del
        02.12.2022 15:31
        +1

        Машинный код после 1960-го года использовали только в программируемых калькуляторах

        Для ПЛИС и сейчас иногда возникает необходимость заюзать машинный код в рамках микропрограммного конечного автомата, ассемблер рожать под это дело выглядит оверкилом обычно.


        1. YuriPanchul
          02.12.2022 20:50
          +1

          Даже в этом случае такие операции как правило обозначают символическими констрантами


  1. onets
    01.12.2022 06:48

    А тогда программистам тоже платили 100500 денег в секунду?

    А удаленка была?)


    1. YDR
      01.12.2022 09:21
      +1

      конечно была. Были очень удаленные от столицы регионы, а были - не очень удаленные. Еще файлы бывали удаленными.

      Ну и на BBS можно было дозвониться, иногда даже на скорости 9600


      1. axe_chita
        01.12.2022 10:34
        +1

        Не правильно, у Амстрада из статьи модем был на 2400, без MNP5:)


  1. lea
    01.12.2022 09:11

    Как программист из 2022-го вы сталкивались с ассемблером разве что на лабораторных работах в университете.

    Иногда в реальных задачах что-то на интринсиках изображать приходится))


  1. ibnteo
    02.12.2022 23:30

    У меня первый комп появился в 1991 году, это был БК-001/01 с магнитофоном, подключался к телевизору. Потом был прокачан до чёрно-белого монитора, для цветных игр был доработан, чтобы выводил вместо цвета градации серого. Затем был приобретён 5.25" дисковод, потом 3.5" дисковод, и наконец 40 МБ винчестер, и более мощный компьютер БК-0011М. Для разработки был доступен Бейсик, Фокал, ну и ассемблер, более навороченный, со множеством способов адресации. На ассемблер рано или поздно приходится перейти, чтобы добиться большей производительности. Причём до этого программировали на нём прямо в машкодах, восьмиричное представление команд довольно удобно читается для архитектуры PDP-11, но не хватало меток, при относительной адресации надо самому считать длину смещения.

    Практически весь софт для БК был написан энтузиастами, кроме игр было большое количество прикладного софта и утилит, на БК-0011М было достаточно памяти (128 КБ) для реализации чего угодно, на БК-0010 приходилось сильно ужиматься, чтобы программа влезла в 16 КБ, или в 28 КБ при использовании 1/4 экрана для вывода информации. Было написано множество дисковых операционных систем, самые популярные это ANDOS и MKDOS, поставлялись с файловыми менеджерами типа Norton Commander.