Должен ли я попробовать заняться практическими проблемами в сборке? [закрыто]

9

Я смотрел на Проект Эйлера Задача 48 :

Серия, 1 1 + 2 2 + 3 3 + ... + 10 10 = 10405071317.

Найдите последние десять цифр серии: 1 1 + 2 2 + 3 3 + ... + 1000 1000 .

В Python я могу сделать это одной строкой:

sum((x**x for x in xrange(1,1001))

Но эквивалент этого ассемблера будет 100 строк и настоящий вызов.

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

Nishant
источник
2
Если вы не знаете, как работает память, как вы можете рассчитывать на такие темы, как указатели? Если вы не понимаете, как работает компьютер и операционная система, как вы можете запрограммировать приложение?
Ramhound
Я могу сделать много абстракций Ramhound, поэтому я и спросил тебя об этом. Я мог бы не получить полное представление об указателях, которые по-прежнему способны что-то делать в указателях, таких как подкачка, что имеет логический смысл, если вы предполагаете, что указатели хранят в памяти какой-либо другой тип данных. темы, которые я должен прочитать? Язык ассемблера и немного COA было бы хорошо?
Nishant
Если вы не получите полное представление о указателях, вы обнаружите, что в некоторых местах это является серьезным недостатком.
Дэвид Торнли
3
Либо ваша строка Python вычисляет x ^ 2 для x в 1..1000 (вместо x ^ x для x в 1..1000), либо python еще более волшебен, чем я думал. :)
Инго
Является ли функция "поднять к власти" *в Python?

Ответы:

1

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

Например, просто понимание того, как составляются простые утверждения. Следующая функция,

int func(int val)
{
  int num = val * 5;
  return num;
}

... становится (по крайней мере, интересным):

movl    %edi, -20(%rbp)
movl    -20(%rbp), %edx
movl    %edx, %eax
sall    $2, %eax
addl    %edx, %eax

Этот код берет аргумент из стека (val, параметр в func), сдвигает его влево на 2 позиции (умножить на 2 ^ 2 или 4) и затем добавляет исходное значение к результату. Конечным результатом является умножение на 5. Пример, подобный этому, иллюстрирует ряд вещей, о которых нужно знать, таких как оптимизация компилятора. Вместо того, чтобы вызывать инструкцию для прямого умножения на 5, она сдвигает два места для умножения на 4, а затем добавляет исходное значение. Подобные примеры я нашел, чтобы значительно улучшить мое понимание вещей на более низком уровне.

Генерируйте вывод ассемблера из gcc с -Sопцией. Однако следует помнить, что результаты будут зависеть от компилятора и уровня оптимизации.

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

Мистер Шикаданс
источник
11

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

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

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

Мартин Беккет
источник
На самом деле, некоторые относительно умные реализации не могут сделать for i in range(1000000): s = s + '.'(намного) хуже, чем «оптимизированные» версии, которые я повторно использую s. Точно так же несколько других разработок лишают законной силы то, что является разумным предположением со знанием C и предполагающим наивную реализацию. Но в целом это больше полезно, чем вредно. Просто помните, что языковые реализации иногда умнее вас;)
2
@delnan - Мне просто нужен короткий пример того, как что-то, что выглядит безобидным в Java / C #, может быть очень дорогим на кремнии. Я особенно сталкивался со многими людьми, которые думают, что большое выделение памяти и копирование происходит мгновенно.
Мартин Беккет
Ненавижу верить, что Делнан :-)
Nishant
5

Хороший вопрос. Обучение сборке определенно хорошо и стоит усилий.

  1. Такое низкое понимание будет полезно при разработке встроенного программного обеспечения
  2. Рефакторинг на низком уровне
  3. Это поможет вам эффективно использовать отладчик
  4. Дать вам понимание дизассемблированного кода, чтобы помочь в таких вещах, как пещеры кода
Адитья П
источник
2
Мне пришлось искать кодеки. Я часто ими пользуюсь, но сейчас мы называем их «обходными путями». research.microsoft.com/en-us/projects/detours
ProdigySim
1

Да и нет.

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

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

Если вы не в оптимизированный код, то вы, вероятно, никогда не увидите преимущества, равные усилиям, которые вы вкладываете.

Skeith
источник
1

Я много работал на ассемблере, когда был моложе, и я не думаю, что это помогло понять что-либо вне ассемблера. Если вы посмотрите на современный ассемблер, то все равно это все на макроязыке. Я обычно ненавижу аналогии, но здесь все равно идет речь: делает ли знание того, как работает двигатель автомобиля, лучший водитель?

Ян
источник
Знание того, как работает двигатель автомобиля, делает вас лучшим водителем? Нет, но это делает вас лучшим владельцем автомобиля, потому что, если двигатель сломается, вы можете это исправить.
Кэмерон Мартин
Согласен, но это не делает вас лучшим водителем, это аналогия, которую я использовал. Устанавливая двигатель самостоятельно, вы не поддерживаете более широкую экономику, используя механику, ... Аналогии имеют свои пределы. В общем, я бы никогда не отговаривал кого-либо искать что-то интересное, если им это интересно, но я думаю, что вам нужно пройти довольно глубоко в кроличью нору, чтобы иметь возможность с пользой применять его к языкам более высокого уровня. Для начала вам нужно понять оптимизацию компиляции, используемую конкретным языком, если он компилируется, или интерпретатор, или джиттер. Это огромная территория.
Ян
1

Я работал над пониманием ассемблера, написав программы на языках более высокого уровня, а затем заменив части (по крайней мере, надеюсь) функционально эквивалентными участками собранного кода. Это означает, что я могу использовать HLL для того, что они хороши для организации и решения проблем высокого уровня, и я использую asm для удара по металлу.

(Когда я говорю о программе хоста, записываемой в HLL, я имею в виду C или ObjC, когда я пытаюсь изучить asm x86_64, и BASIC, когда я работаю над asm Z80, 6502 и 6809).


источник