組み立ての問題を練習しようとすべきですか?[閉まっている]


9

私はProject Euler Problem 48を見ていました。

シリーズ、1 1 + 2 2 + 3 3 + ... + 10 10 = 10405071317。

シリーズの最後の10桁、1 1 + 2 2 + 3 3 + ... + 1000 1000を見つけます。

Pythonではこれを1行で行うことができます:

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

しかし、これに相当するアセンブリは100行であり、実際の課題です。

これらのパズルのいくつかをアセンブリで実行して、低レベルのプログラミングに関する洞察を得て、コンピューターが実際にどのように機能するかを理解する必要がありますか?


2
メモリがどのように機能するかがわからない場合、ポインタなどのトピックをどのように処理することが期待できますか?コンピュータとオペレーティングシステムがどのように機能するかを理解していない場合、アプリケーションをどのようにプログラムできますか?
ラムハウンド2011

私はラムハウンドの多くの抽象化を行うことができるので、私はあなたにこれを尋ねました。ポインタが他のデータ型のメモリ位置を格納していると仮定すると、ポインタの完全なハングがスワッピングなどのポインタ内の何かを実行できるわけではない可能性があります。私が読むべきトピック?アセンブリ言語と少しのCOAは良いでしょうか?
Nishant 2011

ポインタの完全なハングが得られない場合、場所によっては深刻な欠点になることがわかります。
David Thornley、2011

3
Pythonの行が1..1000のxのx ^ 2を計算するか(1..1000のxのx ^ xの代わりに)、または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を直接乗算する命令を呼び出す代わりに、2桁シフトして4を乗算し、元の値を追加します。このような例を見つけて、下位レベルでの理解を大幅に向上させました。

-Sオプションでgccからアセンブラ出力を生成します。ただし、結果はコンパイラと最適化レベルによって異なることに注意してください。

とにかく、私はアセンブリ言語プログラマであるということは、アセンブリ理解することと同じだとは思いません。繰り返しになりますが、Cのような言語でプログラミングし、それがマシンコードにどのように組み込まれるかを知ることは貴重な習慣だと感じています。


11

おそらく、実際にアセンブラを書くことができる必要はありません(そのほとんどは、システムの初期化と呼び出し規約の詳細です)。

ソースなしで何かをデバッグしようとしている場合に備えて、いくつかを理解する価値があります。

しかし、少なくとも 'C'のレベルのマシンとポインタ(基本的には高レベルのアセンブラ)を理解することは間違いなく価値があるので、ループで100万回文字列を連結することが悪い理由を理解できます。


実際、いくつかの比較的賢い実装ではfor i in range(1000000): s = s + '.'、再利用した「最適化された」バージョンよりも悪くなることはありませんs。同様に、他のいくつかの開発では、Cの知識を使用して合理的な仮定を無効にし、単純な実装を仮定しています。しかし、一般的には、害を及ぼすよりも有用です。言語の実装はあなたより賢い場合があることを覚えておいてください;)

2
@delnan -Java / C#で無害に見えるものがシリコン上で非常に高価になる可能性がある場所の短い例が必要でした。特に、大量のメモリの割り当てとコピーはすぐにできると思う人がたくさんいます。
Martin Beckett

そのデルナンを信じたくありません:-)
Nishant

5

良い質問。アセンブリの学習は間違いなく優れており、努力する価値があります。

  1. このような低レベルの理解は、組み込みソフトウェアの開発に役立ちます。
  2. 低レベルでのリファクタリング
  3. デバッガを効果的に利用するのに役立ちます
  4. 逆アセンブルされたコードについて理解し、コード洞窟などで役立つ

2
私はコードキャビティを調べなければなりませんでした。私はよく使っていますが、今では「迂回路」と呼んでいます。research.microsoft.com/en-us/projects/detours
ProdigySim

1

はいといいえ。

それはあなたのコードが何をしているか、そしていくつかのことが単に悪い考えである理由についてのあなたのより良い理解をあなたに与えることは事実ですが、あなたは努力について考えなければなりません。

アセンブラーの学習は週末のプロジェクトではありません。多くの時間がかかり、この時間をよりよく使うことができるかどうかを考える必要があります。

最適化されたコードに慣れていない場合は、投入した労力と同等のメリットが得られることはおそらくありません。


1

私は若いときにたくさんのアセンブラーを作りましたが、それがアセンブラー以外のことを理解するのに役立ったとは思いません。最新のアセンブラーを見ると、とにかくすべてがマクロ言語のものです。私は通常、類推を嫌いますが、とにかくここに行きます:車のエンジンがどのように機能するかを知っていると、あなたはより良いドライバーになりますか?


車のエンジンがどのように機能するかを知っていると、あなたはより良いドライバーになりますか?いいえ、でもエンジンが故障しても修理できるので、あなたはより良い車の所有者になります。
Cameron Martin、

同意しますが、それはあなたがより良いドライバーになるわけではありません。それは私が使っていたアナロジーです。エンジンを自分で修理することにより、力学を使用してより広い経済をサポートすることはできません...アナロジーには限界があります。一般に、誰かが興味を持って何かを学ぶのを探すのをやめさせることは決してありませんが、それをより高いレベルの言語に有用に適用できるようにするには、ウサギの穴をかなり深く掘り下げる必要があると思います。まず、特定の言語で使用されているコンパイルの最適化、またはそれがコンパイルされている場合、またはインタープリター、またはジッターを理解する必要があります。広大なエリアです。
イアン、

1

アセンブラーの理解に取り組んできた方法は、高水準言語でプログラムを作成し、パーツを(少なくとも願わくば)機能的に同等のアセンブルされたコードで置き換えることです。つまり、HLLを使用して高レベルの問題を整理および解決するのに適していることを意味します。また、金属を強打するためにasmを使用します。

(私がHLLで記述されているホストプログラムについて話すとき、私はx86_64 asmを学習しようとしているときはCまたはObjC、Z80、6502および6809 asmを扱っているときはBASICを意味します)。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.