Будет ли когда-нибудь причина писать код в чистом двоичном виде? - PullRequest
13 голосов
/ 20 февраля 2010

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

Ответы [ 18 ]

9 голосов
/ 20 февраля 2010

Еще в 1997 году я делал это на калькуляторах TI-83, когда учился в школе и не имел доступа к кабелю связи.

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

Примечание Конечно, было забавно, если в программе была ошибка, потому что она могла легко повредить всю оперативную память калькулятора.Тогда вам придется удерживать кнопку ON и / или вынимать батарейки AAA и надеяться, что этого будет достаточно для восстановления калькуляции (без каких-либо программ, которые были в памяти).В противном случае, чтобы сделать полный сброс, вам придется использовать отвертку, чтобы открутить специальную резервную батарею.Хорошие времена ...

8 голосов
/ 20 февраля 2010

Историческая причина: Вы работаете на машине, для которой требуется, чтобы ее загрузочный код был включен на передней панели.(И да, это было сделано. Регулярно в первой паре поколений машин.)

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

4 голосов
/ 20 февраля 2010

Вы получили это - если нет ассемблера [dis].Я был в ситуациях хакерской прошивки, где я провел достаточно времени, просматривая необработанные потоки команд PowerPC, чтобы иметь возможность распознавать и собирать вручную несколько видов инструкций.(В итоге я портировал дизассемблер: http://homepage.mac.com/potswa/source/DisDave.sit,, если вам удастся установить его.)

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

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

3 голосов
/ 20 февраля 2010

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

Хотелось бы найти исходный код для него, я на самом деле написал симулятор машины и компиляцию для языка машины.Удивительно, сколько работы можно выполнить с 1024 байтами памяти!:)

3 голосов
/ 20 февраля 2010

Динамическая генерация кода:

Если вам нужно решить очень простую задачу, а производительность важна, часто полезно проанализировать пространство задач и сгенерировать специализированную функцию на лету, чтобы решитьпроблема.

Один практический пример: высокопроизводительная математика с разреженными матрицами.

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

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

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

3 голосов
/ 20 февраля 2010
2 голосов
/ 20 февраля 2010

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

В школе мне приходилось исправлять код в памяти с помощью отладчика без помощи ассемблера. Несмотря на занимательность, этот навык практически не имеет значения вне отладки встроенных систем.

Кроме того, учтите, что мнемоника кода операции, используемая в сборке, должна иметь соответствие 1: 1 фактическим кодам операции (таким образом, термин «мнемоника»), поэтому вы не сможете ничего сделать, набрав машинный код вручную, не мог сделать в сборе. Роль ассемблера состоит в том, чтобы преобразовать мнемонику в коды операций (также определяя, какую версию конкретной инструкции следует использовать - например, непосредственные или косвенные MOV), метки для адресов и аналогичные задачи.

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

2 голосов
/ 20 февраля 2010
  1. с использованием недокументированных кодов операций (все еще присутствующих на некоторых современных процессорах!) Пришлось делать это не так давно на процессорах на базе 6502.
  2. при прошивке программы в домашние схемы смикроконтроллер.В наши дни микроконтроллеры полезны для самых разных вещей.
2 голосов
/ 20 февраля 2010

Я помню, что читал, что Воз написал первый Apple BASIC (Apple I? Apple II?) На машинном языке.Прежде чем у них были запоминающие устройства, вам нужно было ввести шестнадцатеричные коды на мониторе.

1 голос
/ 20 февраля 2010

Вы получаете выгоду от работы с необработанным машинным кодом, а не только на ассемблере. Например, рассмотрите возможность отправки двоичного файла по электронной почте, но с программой электронной почты, которая не знает, как декодировать вложения. Одно время несколько человек писали небольшие программы, которые могли бы декодировать остальную часть вложения, но все в программе было печатным символом. Таким образом, вы декодируете свое вложение, сохраняете тело письма как whatever.com, а затем выполняете его. Он расшифрует вложение и напишет двоичный файл, который вы затем сможете выполнить.

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

Глядя на секунду, я вижу, что у меня все еще есть исходный код для одной из моих попыток:

.model tiny,c
.286
.code
.startup
main proc
    mov     si,offset count
    inc     byte ptr [si]
    mov     al, [si]
    mov     bx,4090h
    shr     al, 4
    call    convert
    lodsb
    and     al,0fh
    mov     byte ptr end_convert, 08bh
convert:
    add     al,bl
    daa
    adc     al,bh
    daa
    int     29h
end_convert:
    ret
    db      0d6h
;    mov     dx, si
    mov     ah,3ch
    xor     cx, cx
    int     21h
    xchg    bx, ax
    mov     dx,offset main
    mov     cx,offset the_end - offset main
    int     21h
    ret
main endp

count:
        db 0
name:
        db 'c.com', 0
the_end:
    end

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

...