質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
アセンブリ言語

アセンブリ言語とは、機械語を人間にわかりやすい形で記述した低水準言語です。

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

CPU

CPUは、コンピュータの中心となる処理装置(プロセッサ)で中央処理装置とも呼ばれています。プログラム演算や数値計算、その他の演算ユニットをコントロール。スマホやPCによって内蔵されているCPUは異なりますが、処理性能が早いほど良いとされています。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

11回答

19957閲覧

アセンブリ言語を使うメリットについて。

carnage0216

総合スコア194

アセンブリ言語

アセンブリ言語とは、機械語を人間にわかりやすい形で記述した低水準言語です。

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

CPU

CPUは、コンピュータの中心となる処理装置(プロセッサ)で中央処理装置とも呼ばれています。プログラム演算や数値計算、その他の演算ユニットをコントロール。スマホやPCによって内蔵されているCPUは異なりますが、処理性能が早いほど良いとされています。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

1クリップ

投稿2018/02/17 16:23

編集2018/02/18 23:32

アセンブリ言語を使っている方にお聞きしたいのですが、使用しているCPUあるいはGPUの構造を細かい部分(メモリ、レジスタ、演算回路など)を把握したうえでアセンブリ言語を扱っているのでしょうか?
逆にハードウェアの知識が浅いとアセンブリ言語は理解できないのでしょうか?

C言語において勉強中なのですが、CPUなどを使いこなすのにアセンブリ言語を勉強している人などがいるなどの記述があったので気になりました。
個人でも調べると確かにハードウェアを理解したうえでアセンブリ言語などの低級言語から高級言語のプログラムを作るなどありました。またファイル操作などのアセンブリコードなども書いてありました。
アセンブリ言語でここまで制御できるのは流石だと感動しました。

ただ、アセンブリ言語を使っている方が使っているCPUのハードを理解してからアセンブリ言語を使うのか、C言語をアセンブリ言語の出力にしてCPUの動作などから構造を把握して、アセンブリ言語でプログラムを作っているのか気になりました。
そしてどちらにしてもなぜアセンブリ言語を使っているのか教えていただけると勉強になります。

もしかしたら編集などして質問が増えたりするかもしれませんがどうかよろしくお願いいたします。

(編集した内容です)

(NASMで作成) ; ----- スタート(ファイル読込) ASSEMBLE: ORG 0X0100 ; セグメント指定 MOV AX,0X3D00 ; AH:0X3D->ファイルオープン、AL:0X00->読込指定 MOV DX,FILENAME ; DX:ファイルパスのメモリアドレス INT 0X21 ; システムコール(戻り値:AX->ファイルハンドル) JC ASM_END ; 読込失敗 ; ----- 読込成功 FILE_OK MOV SI,AX ; ファイルハンドル保存 MOV BX,AX ; ファイルハンドル MOV AX,0X3F00 ; AH:0X3F->読込 MOV CX,64-1 ; CX:読込バイト数 MOV DX,BUFFER ; 読込データ展開番地 INT 0X21 ; システムコール(戻り値:AX->実際に読み込んだバイト数) ; ----- 終了 ASM_END: MOV AH,0X3E ; AH:0X3E->ファイルクローズ MOV BX,SI ; ファイルハンドル INT 0X21 ; システムコール(戻り値なし) MOV AH,0X4C ; AH:0X4C->プログラム終了 INT 0X21 ; システムコール(戻り値なし) ; ----- メモリ FILENAME: DB 'TEXT.TXT' ; ファイルパス BUFFER: RESB 64 ; メモリ確保 ***** ***** ***** ***** ***** ; ----- スタート(ファイル書込) ASSEMBLE: ORG 0X0100 ; セグメント指定 MOV AX,0X3D01 ; AH:0X3D->ファイルオープン、AL:0X01->書込指定 MOV DX,FILENAME ; DX:ファイルパスのメモリアドレス INT 0X21 ; システムコール(戻り値:AX->ファイルハンドル) JC ASM_END ; 読込失敗 ; ----- 書込成功 FILE_OK PUSH AX ; ファイルハンドル待避 MOV BYTE[BUFFER],0X41 ; [ A ]と出力 POP BX ; ファイルハンドル回帰 MOV AX,0X4000 ; AH:0X40->ファイル書込 MOV CX,0X01 ; 書込バイト数 MOV DX,BUFFER ; 書込データの番地 INT 0X21 ; システムコール(戻り値:AX->書込バイト数) ; ----- 終了 ASM_END: MOV AH,0X3E ; AH:0X3E->ファイルクローズ MOV BX,SI ; ファイルハンドル INT 0X21 ; システムコール(戻り値:なし) MOV AH,0X4C ; AH:0X4C->プログラム終了 INT 0X21 ; システムコール(戻り値:なし) ; ----- メモリ FILENAME: DB 'TEXT.TXT' ; ファイルパス BUFFER: RESB 64 ; メモリ確保 ***** ***** ***** ***** ***** ; ----- スタート(ファイル作成) ASSEMBLE: ORG 0X0100 ; セグメント指定 MOV AH,0X3C ; AH:ファイル作成時→0X3C:ファイル上書、0X5B:エラー MOV DX,FILENAME ; DX:ファイルパスのメモリアドレス MOV CX,0X0000 ; CX:0X0000->通常ファイルの作成、0X0001->読込専用ファイルの作成 INT 0X21 ; システムコール(戻り値:なし) JC ASM_END ; 作成失敗 ; ----- 作成成功 FILE_OK ; ----- 終了 ASM_END: MOV AH,0X3E ; AH:0X3E->ファイルクローズ MOV BX,0X00 ; 初期化 INT 0X21 ; システムコール(戻り値:なし) MOV AH,0X4C ; AH:4C->プログラム終了 INT 0X21 ; システムコール(戻り値:なし) ; ----- メモリ FILENAME: DB 'TEXT_NEW.TXT' ; ファイルパス ***** ***** ***** ***** ***** ; ----- スタート(ファイル削除) ASSEMBLE: ORG 0X0100 ; セグメント指定 MOV AH,0X41 ; AH:ファイル削除指定 MOV DX,FILENAME ; DX:ファイルパスのメモリアドレス INT 0X21 ; システムコール(戻り値:なし) JC ASM_END ; 削除失敗 ; ----- 削除成功 FILE_OK ; ----- 終了 ASM_END: MOV AH,0X3E ; AH:0X3E->ファイルクローズ MOV BX,0X00 ; 初期化 INT 0X21 ; システムコール(戻り値:なし) MOV AH,0X4C ; AH:4C->プログラム終了 INT 0X21 ; システムコール(戻り値:なし) ; ----- メモリ FILENAME: DB 'TEXT_DEL.TXT' ; ファイルパス

ちなみに、載せましたファイルを開くアセンブリ言語プログラムは使うCPUの構造をレジスタや細かいレベル(演算回路にデータをおくるレジスタなど、文字を表示するためのデータを送るレジスタなど)まで理解して作ったのですか?

だとしたら、何をもとに使っているCPUの内部構造を把握したのでしょう

か?

個人的にはアセンブリ言語はCPUに依存するため使うCPUの構造を詳しく知らないとプログラム自体組めない様にも思えます。

また、質問とは真逆にアセンブリプログラムからわからない情報は何かありますか?

編集後で申し訳ありませんがどうかよろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答11

0

ベストアンサー

こんにちは。

C言語において勉強中なのですが、CPUなどを使いこなすのにアセンブリ言語を勉強している人などがいるなどの記述があったので気になりました。

アセンブラでギチギチにハードウェアを制御すれば最大限の性能を引き出せますが、その方法で大規模なプログラムを開発することはあまり現実的ではありません。生産性が低すぎてお金がかかりすぎるのです。そのため、そこまでやるのは処理速度が最重要なごく一部の分野の狭い範囲に限定されます。
多くの人は、そのようにして開発されたデバイスドライバやライブラリを用いて、それなりの速度で動作するプログラムを開発し、生産性を確保します。

この速度と生産性のトレードオフは対象のプログラムで大きく振れます。生産性命の分野もあれば速度命の分野もあります。C言語は速度命に近い分野のプログラムで良く使われます。ですので、ハードウェアの特性を把握していれば居るほど有利になる(より高速なプログラムを開発できる)というわけです。
そのためにアセンブラを勉強することはかなりお薦めです。


【質問の追記への回答】

だとしたら、何をもとに使っているCPUの内部構造を把握したのでしょうか?

最初はやはりアセンブラの入門書で学習するのが良いように感じます。情報処理技術者試験のCASLなどなら入門書もあるように思います。

実際のハードウェアを制御してみたいのであれば、ATEMLのAVRPICならばハードウェアも廉価ですし、情報も豊富です。(個人的には構造が素直なAVRがお勧めです。)

個人的にはアセンブリ言語はCPUに依存するため使うCPUの構造を詳しく知らないとプログラム自体組めない様にも思えます。

その通りです。しかし、いきなりPCのCPUから始めるのは難しすぎるのでお勧めではありません。
私自身はまだCPUが単純だった頃からこの分野に興味を持ちましたので、上記のAVRマイコンよりも更に簡単なマイコンから入りました。その流れ自体は正解だったと思います。

まずは、基本のメモリやレジスタの仕組みをマスターすることが重要と思います。その辺りを把握しているのとしていないのとでは、C言語で書けるプログラムの質が結構変わると思います。

投稿2018/02/17 17:17

編集2018/02/19 04:38
Chironian

総合スコア23272

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

carnage0216

2018/02/17 17:51

解答どうもありがとうございます。 デバイスドライバってアセンブリ言語で作れるのですか?(作るつもりはありません。
episteme

2018/02/18 00:12

アセンブリで作れなければ他のどんな言語でも作れない。 (ドライバがすべてアセンブリで書かれているとは言っていない)
Chironian

2018/02/18 06:58

epistemeさん、フォローありがとうございます。 carnage0216さん、epistemeさんのフォローの通りです。 工数を度外視すればアセンブラで作れないプログラムはありません。ドライバの大半はCやC++で書かれていると思います。ギチギチに高速化したいような狭い範囲のみアセンブラが使われている場合があります。
carnage0216

2018/02/19 05:54

お二方、どうもありがとうございます。 勉強になりました。
carnage0216

2018/02/19 05:56

今はまだ、pcのCPUを扱うのは難しいので行えませんが、pcのCPUを扱う上で、そのCPUへは、データシートを見ながらアセンブリプログラムを作るのですか?
Chironian

2018/02/19 06:17

そういうことになります。PCに限らず、どのCPUを使う場合も、そのCPUの仕様書を見ます。 ですので、その仕様書が分厚いものは厳しいですね。 CASLのCOMETはコアしかないので数ページくらいかも。 AVRなどは周辺もあるので数十ページですが十分に見れる量です。有志の方たちが日本語に訳しているものがかなり揃っています。 PCのCPUの仕様書は見たことはないですが、コア部分だけでも数100ページ超えるのでは? 恐らく英語しかないと思います。
carnage0216

2018/02/20 16:05

どうもありがとうございます。PICマイコンやAVRマイコンのアセンブリ命令と今現在使われているインテルのCPUのアセンブリと何か違いはあるのでしょうか? 細かい部分では違いはあると思うのですが、マイコンとCPUのアセンブリプログラムを素人の私なりに見比べると大きな違いは無いように思えます。(間違っていたら申し訳ありません。)
Chironian

2018/02/20 17:35

アセンブラの文法はどのアセンブラでも似通っていますので、パッとみると同じように見えるかも知れません。 しかし、異なるメーカのCPUはアセンブリ命令1つ1つが事実上全て異なります。 そして、先にも書きましたようにATMELとIntelのCPUを比べると、CPUの規模が大幅に異なるので仕様書の厚さが違います。分厚い仕様書を読み下して適切な命令を見つけるのはたいへんですよ。 再度しかし、小さいもの、大きいものあれど基本的なコンピュータの仕組みは大差ないです。 ですので、分厚いCPUの仕様書を読む苦労をするより、薄いもので学習した方が基本的なコンピュータの仕組みを学ぶには効率が良いです。(恐らく月とスッポン程の差があるでしょう。)
carnage0216

2018/02/20 18:03

分厚い仕様書を読むのと薄い仕様書を読む上での効率の差が月とスッポン程の差という意味ですか? 大差ないなら薄い仕様書を読むのが良いというわけですね。私も同意見であります。
carnage0216

2018/02/20 18:12

そして、今、色々な方から貴重なアドバイスを頂いた事で考えているのですが、PICマイコンでアセンブリ言語を学ぶべきか、ラズパイでアセンブリ言語を学ぶべきか迷っています。 今の目標として、ラズパイならばLinuxで画像処理を行いたいです。画像処理に使うのはopencvです。opencvとLinuxのシステムコールをアセンブリ言語として出力してみてハードウェアでどの様に動くのか理解し、次により高速化できるよう改造したりして見たいと考えていますが、過去にPICマイコンを少しいじっただけの私のスキルでは荷が重い気がしますが、やって見たい気持ちが強いです。 ただ、残念なのはPICマイコンの様にラズパイのアセンブリ言語での参考書はなく、情報が少ないということです。 ラズパイのアセンブリでわからない度にこちらに質問していては身につきませんし、悩んでおります。 長文失礼いたします。
Chironian

2018/02/21 02:23

ラズパイはARMコアです。これもインテルCPUとまではいかなくても、かなり大規模なCPUです。 そして、Linuxの上でアセンブラでハードウェアを制御するということは、Linuxのカーネル・モードのプログラミングの作法も学習する必要があります。これはこれで有用ですが、コンピュータの基本的な仕組みを把握していないとなかなか理解できないと思います。 次にPICはアドレスとデータのビット数が異なるという結構特殊なCPUです。C言語はアドレスとデータのバス幅が同じCPUの方が素直に構成できる文法になっていますし、殆どのCPUはアドレスとデータのビット数は同じです。ですのでC言語を使いこなす力を伸ばすためのアセンブラ学習に適切なのか疑問を感じます。 PICのライバルにあたるものにATMELのAVRマイコンがあります。こちらはアドレスとデータのビット数が同じでC言語にも向いたCPUです。ここでもちらほら質問があがるArduinoもAVRですね。 https://ja.wikipedia.org/wiki/Arduino https://avr.jp/ ところで、AVRを押してますが私は関係者ではないです。PICとAVRの両方でC言語とアセンブラを使った経験からの記述です。(なおARMでアセンブラを使ったことはないです。)
Chironian

2018/02/21 06:55

ごめんなさい。ちょっと間違った表現になってしまいました。 「PICはアドレスとデータのビット数が異なる」は間違っています。 「PICは命令を記録するメモリ空間とデータを記録するメモリ空間が完全に分離しています。それぞれのビット数も異なります。」の方が正しいです。https://sanuki-tech.net/pic/overview/architecture/
carnage0216

2018/02/21 15:33

Chironianさん、どうもありがとうございます。 PICは触ったことがあるのですが、AVRは触ったことはありません。 すこし不安なのがAVRは資料が少ないため私でもできるか不安なことです。PICは難しいですがとりあえず資料や参考書があるため私でも取り組めています。 ラズパイにおいては買うか買わないか迷っています。 ただLinuxを導入してどのようにプログラムがどのように動くのかを勉強するのにいいかもと思っています(思っているだけで実行できるだけのスキルはありません。) ちなみにARMは企業名とのことですが、ARMコアやPICのCPUも前回に書いたように大きな違いはないのでしょうか?
Chironian

2018/02/21 16:34

AVRも資料は豊富ですよ。Arduinoでググって見て下さい。 ARMコアとPICでは規模がかなり異なります。PICはARMに比べると小規模でより学習しやすいCPUです。 > ただLinuxを導入してどのようにプログラムがどのように動くのかを勉強するのにいいかもと思っています 良い選択と思いますよ。
carnage0216

2018/02/21 16:52

確かに規模の大きさはありますね。 どうもありがとうございます。
keicha_hrs

2018/02/21 23:08

「Armは大規模だから学習しにくい」と受け取れるコメントにはちょっと異論があります(ARMは社名およびブランド名を変更して現在ではArmと表記するのが正しいらしい)。ArmにはCortex-M0コアのような8/16bitマイコン市場に対抗するような小規模システム向けのものもあり、これが組み込まれたプロセッサーも安価に購入できます。こんなのとか。 http://akizukidenshi.com/catalog/g/gI-07191/ こういったプロセッサーのプログラムをフルアセンブラで記述するのは、そう難度の高いことではないです。また、アセンブリ言語の構造のわかりやすさという点でも、PICなどよりはArmの方が勝っているのではないかとも思います。
Chironian

2018/02/22 03:45

keicha_hrsさん。 なるほどArmにも小規模なCPUコアがあるのですね。
rubato6809

2018/02/22 07:27

ARM32とARM64では、インテルCPUのような命令の互換性は無いようです。例えばこのサイト ・ARM32 https://www.mztn.org/slasm/arm00.html ・ARM64 https://www.mztn.org/dragon/arm6400idx.html こういうサイトがあるので、質問者でもかなりの事を試して学べそうですけどね。ググれば、C言語でLチカしてみたというページも見つかります。C言語でできるなら、アセンブリ言語でもできる。本格的なIOドライバを作れるかどうか、割込を扱えるかどうかは、私にもわからないけど、簡単なIOポートの実験は可能です。 質問者がラズパイに興味を持ってるなら、それだけで十分なアドバンテージですから。
carnage0216

2018/02/22 12:18

keicha_hrsさん、rubato6809さん貴重な資料どうもありがとうございます。
carnage0216

2018/02/22 12:25

ちなみにChironianさんに質問なのですが、ほかの回答者様から頂いたアドバイスである。 「CPUのハードを理解してからアセンブリ言語を使うのか、C言語をアセンブリ言語の出力にして…プログラムを作っているのか(私の質問)」 「コンパイラにアセンブリ言語を出力させて雛形・お手本にします。 CPUにどんなレジスタがあるか、確認するのは基本中の基本だが 命令全てを覚える必要はない。命令解説、命令一覧、擬似命令一覧のような資料があれば十分。 実用上、呼出規則(ABI)の確認は必須。規則を確認できる資料があれば安心確実ですが、関数に引数やreturn文、関数呼出し、グローバル変数等を含めておいてコンパイルしてみればかなりの情報が得られます。(回答者様のアドバイス)」 に関していきなりコンパイルの出力のアセンブリを理解するのはハードルが高いですが、慣れてくれば以上のこともできる可能性はあるのでしょうか?
carnage0216

2018/02/22 12:27

補足しますとCPUのデータシートを読むのとは別に、アドバイスのやり方でもCPUの構造やどのような命令を送ればよいかコンパイルによって出力されたアセンブリからわかるのかを聞きたいです。
rubato6809

2018/02/22 13:24

> CPUのハードを理解してからアセンブリ言語を使うのか、C言語をアセンブリ言語の出力にして…プログラムを作っているのか こういう質問には、ハードを理解し終わるまで何もできない、かのような硬直したものを感じて、もどかしさを感じますね。命令をすべて覚えるまで一切手を出さないつもりですか?実際は、あっちへいったり、こっちへきたり、多面的に経験しながら理解を深めていくものです。 コンパイラが生成したコードをみて、わからない命令があったら資料で調べて構わないんですよ。すでにPC上のCコンパイラを使ってるんでしょ?アセンブリコードを生成させてみることができるはずで、それを見てアタリをつけてみても良いのですよ。インテルCPUは複雑だと、皆が言ってるから、けっして見てはいけない、とか考えてます?バカバカしいw
Chironian

2018/02/22 13:29

アセンブラの基本が判っていたら、C言語のアセンブリ出力を読むのはたいへん有効と思います。そのために全ての命令を把握している必要はないです。出てきた命令を仕様書を見て機能を調べれば十分ですから。 しかし、「CPUの汎用レジスタ、プログラム・カウンタ、スタック・ポインタ、アドレッシング・モード」のようなごくごく基本が判っていないと、アセンブリ出力を読むのは辛いかも知れません。 そこで、規模の小さなCPUの方ならば楽に把握できます。 そして、素直なCコンパイラがあるとそのアセンブリ出力が素直なので理解も捗ります。(PICはここがお勧めではありません。)
carnage0216

2018/02/22 13:36

インテルCPUに関して、出力されたアセンブリ言語も勉強になりますが、それ以前にそのCPUのデータシートを理解していた方が良いのかなと考えただけで、決してインテルCPUの出力されたアセンブリ言語を見ないわけではありません。 わたしの伝え方が悪かったようです。すいません。
rubato6809

2018/02/22 13:47

データシートだって、全ての命令、全ての情報が乗っていなければ使い物にならない、なんてことはなくて、ネット上でみつかる不完全な情報も結構役に立つんですよ。 誰だって最初は初心者、いきなり全てをわかろうとしてはいけない。少しづつ手がかりを増やしていくことが大事。
carnage0216

2018/02/22 13:50

貴重なご意見どうもありがとうございます。
carnage0216

2018/02/27 17:40

今更ながらなのですが、マイコンのAVRは構造が凝っている?と調べてわかったのですが、マイコンの中でもCPUに構造や複雑さが一番似ているのはAVRなのではないでしょうか? 個人的に調べた結果マイコンの中で本格的にPCなどのCPUに使いのはAVRだと思いました。
carnage0216

2018/02/27 19:17

またAVRマイコンの開発ソフトにおいてⅭ言語プログラムのアセンブリ出力などの機能はあるのでしょうか? どうかよろしくお願いいたします。
Chironian

2018/02/28 16:06

> マイコンの中でもCPUに構造や複雑さが一番似ているのはAVRなのではないでしょうか? マイコンはI/Oも1チップのまとめたCPUです。内部にCPUも入っています。 CPUの意味がPCのCPUでしたら、AVRがそれに一番似ているというわけではないです。C言語向きという点では似ていますが、より命令体系が似ているCPUもある筈です。 > AVRマイコンの開発ソフトにおいてⅭ言語プログラムのアセンブリ出力などの機能はあるのでしょうか? それはCコンパイラの機能ですね。私の知る限りアセンブリ出力できないCコンパイラはないです。 AVR用Cコンパイラでアセンブリ出力したことはありませんが、恐らくあると思います。
carnage0216

2018/02/28 16:13

どうもありがとうございます。
guest

0

使用しているCPUあるいはGPUの構造を細かい部分(メモリ、レジスタ、演算回路など)を把握したうえでアセンブリ言語を扱っているのでしょうか?
逆にハードウェアの知識が浅いとアセンブリ言語は理解できないのでしょうか?

ここでいう「ハードウェア」が「メモリ、レジスタ、演算回路など」のCPU内部構成のことだとするなら、それが把握できなければアセンブラは使いこなせません。少なくとも、メモリやレジスタ関連は命令と直結しているので理解する必要があります。
それに加えて、もし高速化のためにアセンブラを使うのなら、キャッシュや命令パイプラインなどの仕組みも理解する必要があります。ただし、その辺は同じ命令セットのCPUでもメーカーや型番によって違いがあるので、ちゃんと把握していないと、あるCPUでは高速化したつもりが別のCPUではそれほどでもない(むしろパフォーマンス低下)という現象も起こり得ます。

そしてどちらにしてもなぜアセンブリ言語を使っているのか教えていただけると勉強になります。

デバイスドライバーは別として、一般のアプリでアセンブラを使う理由は「高速化」ですね。
ただし、ロジックをアセンブラで組むのは今となってはナンセンスです。今時のCPUは内部構造が複雑化しているので、人間がアセンブラで効率的なプログラムを書くのは至難の業です(書けたとしてもその作業行程が超絶非効率です)。

では何のためにアセンブラを使うかというと「C/C++が言語でサポートしていない機能を利用する」ためです。一番判りやすいのがSIMD命令ですかね。x86でいうところのSSEやAVXです。組み込み関数の形(実態はインライン展開)で利用できるようになっています。

投稿2018/02/18 01:17

編集2018/02/18 01:20
catsforepaw

総合スコア5938

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

carnage0216

2018/02/21 15:34

どうもありがとうございました。
guest

0

僕がこのギョーカイに足突っ込んだ頃はフツーにやってました。
CPUもショボかったし、コンパイラの最適化がヘタクソなもんで、生成されたアセンブリをハンド・オプチマイズしてましたね。スピード欲しいとこは機械語で書いてCから呼び出すとか。

今はやらんですねぇ...コンパイラの方がイカした機械語吐いてくれたりするし、なにより開発効率が。

投稿2018/02/17 20:12

episteme

総合スコア16614

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

carnage0216

2018/02/18 06:59

コンパイラの方がイカした機械語を吐き出すとの事ですが、吐き出した機械語を読んで内部で何が起きているかを分析するのですか? アセンブリ言語に変換するとか。
episteme

2018/02/18 07:58 編集

多くのC/C++コンパイラはコンパイル・オプションでアセンブリ/機械語のどっちを吐くか選択できます。 昔はコンパイラの最適化がアレだったので、一旦アセンブリで吐かせ手を加えたのちアセンブラに食わせて機械語作ったり、それが面倒ならCでインタフェースだけ用意してその中で機械語で書いたサブルーチンをcallしたりとか。
carnage0216

2018/02/19 05:50

どうもありがとうございます。
guest

0

マイコンプログラミングの分野では、「アセンブリ言語を使わざるを得ない」場面が多々存在します。

例えば、スマートフォンなどで主流になっているArmマイコンでは、「電源を投入した直後に動作する部分」についてはアセンブリ言語で記述するしか方法がありません。また、マイコンを発売しているベンダーによっては「アセンブラは無償、Cコンパイラは有償」という形で提供していることもあり、そうしたものは費用的な問題でアセンブリ言語を選択することもあります。

質問で想定されている環境とは全く異なる回答だと思いますが、そういう世界もあるという話で。

投稿2018/02/18 07:41

keicha_hrs

総合スコア6768

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

最近はコンパイラがどんなコードを吐くかの確認のために、アセンブリは読むことはあっても書くことは殆ど無いですね。
ソフトウェアパイプラインを意識したアセンブリを普通の人が書くのはとても難しいです。

しかし、アセンブリが読めれば高速化のためにどんなプログラムを書けばよいかのヒントが得られるので勉強するのは有効だと思います。

また、組み込み分野では電源投入後のCPUのスタートアップルーチンを作るためにアセンブリで書くことが多いです。

投稿2018/02/17 18:12

TaroToyotomi

総合スコア1430

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

carnage0216

2018/02/21 15:33

どうもありがとうございます。
guest

0

載せましたファイルを開くアセンブリ言語プログラムは使うCPUの構造をレジスタや細かいレベル(演算回路にデータをおくるレジスタなど、文字を表示するためのデータを送るレジスタなど)まで理解して作ったのですか?

MS-DOSとは懐かしい...

INT 0X21 は機械語レベルのシステムコール。これによって呼び出された先に機能の本体がある。
Cで言うところの標準関数みたいなもんで、呼ぶ側はそんなに細かいこと知らなくていい。

投稿2018/02/18 23:42

episteme

総合スコア16614

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

carnage0216

2018/02/18 23:47

そうなんですか。残念です。 レジスタを指定したりしたかったです。 どうもありがとうございます。
episteme

2018/02/19 07:19 編集

そこはまだ入り口ですわ。目的地はシステムコールをくぐり抜けて行きつく先です。 マシン毎の差異を吸収すべくシステムコールで統一してるわけだから、そこまではどんなPCのMS-DOSでも同じ。Window/LinuxもMS-DOSも、マシン毎の差異を吸収してひとつのアプリがどんなPCでも動く環境を提供するのが目的ですからねー
carnage0216

2018/02/19 05:48

え!入り口とは知らなかったです。 では、システムコールをくぐり抜けて行きつく先とはどこなのでしょうか? レジスタよりももっと細かい制御をするのでしょうか? もはや、アセンブリ言語でも制御が難しいのですか? どうかよろしくお願いします。
episteme

2018/02/19 07:05

だってこのあとハードウェアを相手にせんならんのよ? I/O-portやら割り込みやらDMAやら面倒見んならんもんがてんこ盛り。 それらを全部アセンブリで書くことになります。眩暈がするっしょ?
carnage0216

2018/02/21 10:20

返信が遅くなりました。 たしかに面倒ですがI/O-portやら割り込みやらDMAなどアセンブリ言語で全て書くことが出来ることに感動します。
carnage0216

2018/02/21 13:08

ちなみに、アセンブリはCPU、GPUと一対一で対応しているだけあって、何もかもアセンブリ言語のみでCPU、GPUは制御することは可能なのでしょうか?話の流れから面倒ですが可能だとは思います。 すべてアセンブリのみで制御するということです。
episteme

2018/02/21 13:52

できます。機械語とアセンブリは等価なので。
carnage0216

2018/02/21 15:14

どうもありがとうございます。
rubato6809

2018/02/21 15:21

> たしかに面倒ですがI/O-portやら割り込みやらDMAなどアセンブリ言語で全て書くことが出来ることに感動します 質問者にとって、もはや高性能を求めるといった、古典的(?)な目的ではなさそうですね、そもそも誰にとっても、アセンブリ言語を手書きする事に生産性・可読性・ポータビリティ・・・こうした実用的な意味は無いうえに、今や性能追求さえ人の手では困難なんだから。 それでもアセンブリ言語そのものを体験したい、IOポートや割込みの操作を体験したい、実際、どんな風に動くものか、どんな風に書くものか、ハードウェアに接した領域を身を持って体験したい、それで動作原理やシステムの構成を知りたい・・・そうしたことが目的なんじゃないか。 それは十分意味のあることですよ。実際、マイコン組込みシステムは、まさにそうした分野を扱うから。でも、学問に王道なし、身近に相談できる人・指導してくれる人はいないようだし、今の質問者の段階で、ぱっと展望が開ける「特効薬」を期待されてもねえ。。。 ・・・今夜はこれで寝ますw
carnage0216

2018/02/22 15:47

あの突如なのですが、リンカスクリプトとアセンブリ言語に関係はあるのでしょうか?
rubato6809

2018/02/22 22:49

リンカスクリプト・・・その名の通り、アセンブラじゃなくて、リンカに対する指示ですね。私自身は手を入れた経験皆無で、どこにあるかも知らない、それでも通用するようだ。Cコンパイラ(が使うリンカ)とか開発環境が用意したデフォルトのもので間に合ってるんだと思う。
episteme

2018/02/23 00:40

"直接”の関係はない。コンパイラ/アセンブラが生成するのは機械語とシンボル表。 おなじみ HelloWorld.c をコンパイルして生成された.obj/.o には main() のナカミから作られた機械語。 そして"main が定義された"と"printfを呼んでる"って情報、これがシンボル表。 リンカはシンボル表をかき集めて"呼んでる"と"定義された"とを繋ぎあわせている。
guest

0

アセンブラでのプログラムは、レジスタ名等を直接使うので、そのレベルでは、プロセッサの構造を知らない限りプログラムできません。高位言語で、システムに準備されている関数等を知らずにプログラムできないのと同じ関係です。

勉強の方法は人それぞれだと思いますが、何の知識もないプロセッサのアセンブラをアセンブラの結果だけ見て理解するのは遠回りです。

アセンブラは、CPUの挙動を1ステップづつ記述するので、大部分のときは、CPUの動作とアセンブラの記述は1対1で対応付けることができます。
しかしながら、CPUの動作がその場の状況によって変化する場合は、アセンブラの記述はCPUの動作を記述できません。
割り込み処理、命令のリオーダー、キャッシュ、複数コア間の同期、レジスタのダイナミックな色塗り分岐予測などで、動作の推測が難しくなります。

CPUの構造をレジスタや細かいレベル(演算回路にデータをおくるレジスタなど、文字を表示するためのデータを送るレジスタなど)

CALSなどのモデルですよね。そのレベルでは、アセンブラは十分にCPUの動作を正確に記述でき、しかもたぶんCで書いてもアセンブラで記述してもそれほど性能差はでません。
産業用途では、確実に処理時間を一定にするためにキャッシュを使わない という手法もあります。

投稿2018/02/21 07:00

gm300

総合スコア580

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

一般論でいえば、アセンブリを学ぶメリットは小さいです。コンパイラが対応している限り、高級言語で記述してからコンパイルするほうが普通です。アセンブラを使う利益があるとすれば以下の場合ぐらいに限られます。

1 コンパイラが対応していない。
2 処理速度、省メモリに拘りたい。
例外 出来上がったプログラムの解析

ケース1についてはアセンブラが唯一のプログラミング手段ですので、これは当然です。具体的な例としては組み込み系分野とかスーパーコンピュータの分野です。ただし、いずれも先端分野ですし、「誰かがコンパイラ作ったら、それ以降はあえてアセンブラを使うほどではない」、「コンパイラを作る人が現れないほど狭い分野を学ぶメリットは薄い」といった考え方もあります。

ケース2についても、やはり限定的です。ハードウェアの進歩が早く、技術が身に着く迄に技術が不要になっているとかザラです。

共通して言えることですが「少し待てば大抵メリットがなくなる」ということです。逆にデメリットが大きすぎる(手間が遙かに大きい、環境ごとに必要な知識が異なる等)のでとても割にあうとは思えません。例外として、セキュリティ分野とかデバッグのためのテクニックを学ぶことは利益があると思いますが、ここでの本題ではなさそうなので深く述べません。

投稿2018/02/20 20:00

HogeAnimalLover

総合スコア4830

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

HogeAnimalLover

2018/02/20 20:01

述べ忘れましたが、原理の勉強のためとかであれば価値はありますよ。あくまでも実用面においての意見です。
carnage0216

2018/02/21 10:22

題名にメリットと書いてしまいましたが、ハードウェアを意識しながらアセンブリ言語やC言語が書けるならばデメリットであっても構いません。
guest

0

アセンブリ言語を使っている方にお聞きしたいのですが、使用しているCPUあるいはGPUの構造を細かい部分(メモリ、レジスタ、演算回路など)を把握したうえでアセンブリ言語を扱っているのでしょうか?

CPUの理解が必要です。GPUは扱いたいなら必要なのかもしれませんね。
私はGPUについてはなんらかのライブラリごしにしか触らないので一般知識くらいしか持ってませんけど

逆にハードウェアの知識が浅いとアセンブリ言語は理解できないのでしょうか?

最低限、対象CPUの知識が必要でしょう
遅延スロットなんかは知らない人が見たら難しいだろうなと思います

そしてどちらにしてもなぜアセンブリ言語を使っているのか教えていただけると勉強になります。

機械語の読み書きが人間には難しいのでアセンブリ言語を用います
コンパイラの出力は(一部例外を除き)機械語です。実行中のコードもまた機械語になります。
デバッガを用いてソースのない部分の処理などの機械語を理解したいときにアセンブリ言語を用いています。

書かないのか?と聞かれると面倒だからやりません。
どうしても特殊な命令の利用が必要ならばintrinsicを
どうしても任意の機械語が必要ならばCをコンパイラに食わせ、手を加える事を考えます。

--

追記:2018/02/19 08:32への回答

CPUの構造をレジスタや細かいレベル(演算回路にデータをおくるレジスタなど、文字を表示するためのデータを送るレジスタなど)

普通のwindows等が動いてるCPUをx86互換CPUといいます。
intelが30年前に発売した「intel 80386」というCPUが語源です。
当然今の「Core iシリーズ」と中身はまるで別ものです。
ですが、16bitモードの機械語には互換性があります。
また、Core iのうちでもCoffee Lakeとsandy bridgeは違いますし、Core iとPentium4でも結構違いますが
機械語はほぼ一緒で、かなり高い互換性があります。
更にはAMDが出してる互換CPUなんかも、中身はやっぱり別物です。

つまり、CPUやプログラムというのは入力に対する出力さえ規定しておけば中身を必ずとも知る必要はないという事です。

ちなみにintelのマニュアルです。
私も全文(4670頁)は読めないので、不明な命令等を検索して使っています。

ファイルを開くアセンブリ言語プログラム

int 21hはwikipediaで調べるとMS-DOS APIへリダイレクトされることから分かる通りOSのAPIであり
win32apiと大きく変わるものじゃないです。
当時のcpuの事情から割り込みを使い、レジスタによる受け渡しだっただけです。
今では過去のもので、64bit Windowsでは呼び出す事もできません。

int 13hというBIOSが提供するAPIもありますが、(端的に言えば)OSによって呼び出しが禁止されます。

投稿2018/02/18 07:46

編集2018/02/19 08:57
asm

総合スコア15147

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ハードウェアの知識が浅いとアセンブリ言語は理解できないのでしょうか?

そんな事はないでしょう。
アセンブリ言語の基本は

  • 2進数を理解する
  • メモリ。何ビット単位でアドレスがついているか、エンディアンはビッグかリトルか等
  • CPU内部にどんなレジスタがあるか
  • 各命令の動作を理解する

といった事です。レジスタもメモリも、要するに記憶場所であって、高級言語を学ぶときに変数や配列をイメージするのと本質的な違いはありません。各命令の動作を理解する上で2進数に関する理解は重要です。例えば AND, OR, NOT とか1の補数、2の補数、桁溢れなどが思いつきます。
これらはハードウェアを勉強しなくても理解できることばかりです。

なぜアセンブリ言語を使っているのか

当然ですが、コンパイラはCPUの各命令を平等に全て使うわけではなく、全く使わない命令もあります。コンパイラが扱わない特殊な命令・特別な命令列を使いたい場合があります。そのような特殊な部分を、アセンブリ言語で書いて関数化する、それを高級言語(普通はC言語)から利用する…ことは昔から行われてきました。例外処理などの特殊なライブラリ関数や、Cスタートアップルーチンもアセンブリ言語で書かれます。もっともコンパイラの守備範囲は昔より広がっていて、以前アセンブリ言語だった部分がC言語に置き換えられたケースも見ていますが。

最近の私の経験です。

  • 数年前、コンパイラ任せでなく性能を追求できないものかとゴリゴリ書き始めた時、まさしく特殊な命令・命令列を試すことになりました。趣味なので根性続かず中途半端で終わってます(今から再開しようかw)。
  • 先日たまたま、リンクエラー対策として、アセンブリ言語で提供されているCスタートアップルーチンに手を入れる機会がありました。Cでも対策可能でしたが、処理の本筋に関係ない部分であり、僅か数行の追加で済むことだったので。これは一応組込みのお仕事。

今、アセンブリ言語を使う仕事は本当に微々たる局面しか無いと思います。それでもアセンブリ言語を学ぶのは、ブラックボックスを解消し、コンピュータおよび言語処理系の動作原理を具体的に実感できる意義があると思います。オブジェクト指向も連想配列も何もかも…全て単純な命令の組み合わせで実現されているのだから。そうしたことを知るのは、やはり上手な利用につながるのではないですか。さらに、ハードウェアの理解が助けになる分野もあります。貴方が関係するとは限らないけど。

追記

CPUのハードを理解してからアセンブリ言語を使うのか、C言語をアセンブリ言語の出力にして…プログラムを作っているのか

コンパイラにアセンブリ言語を出力させて雛形・お手本にします。

  • CPUにどんなレジスタがあるか、確認するのは基本中の基本だが
  • 命令全てを覚える必要はない。命令解説、命令一覧、擬似命令一覧のような資料があれば十分。
  • 実用上、呼出規則(ABI)の確認は必須。規則を確認できる資料があれば安心確実ですが、関数に引数やreturn文、関数呼出し、グローバル変数等を含めておいてコンパイルしてみればかなりの情報が得られます。

プログラミング言語をひとつ使えるようになれば次の言語は楽に覚えられる、と同じで、アセンブラもひとつ経験すると別のアセンブラでも見当がつくようになります。

投稿2018/02/18 03:00

編集2018/02/18 04:55
rubato6809

総合スコア1380

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

rubato6809

2018/02/18 14:36

「CPUのハードを理解してからアセンブリ言語を使う」・・・この人の問いは、CPU内のレジスタ構成を知ること、それが「CPUのハードを理解」することなんだね。それなら、「ハードウェアの知識が浅いとアセンブリ言語は理解できない」が答えです。ターゲットCPUのレジスタを知らずにアセンブリ言語が分かるなんて事、ありえませんから。私の答えは外したようです笑。 質問者は機械学習云々という質問をしていたけど(私は機械学習、門外漢だけど)、そういう人が今の段階でアセンブリ言語に手を出さなきゃいけない必要性があるんだろうか?とは素朴な疑問です。 たぶん、何をすべきか迷っていて、出発点の辺りをぐるぐる回ってるだけで一向に目的地に近づかない、そんな焦りじゃないですか。身近に相談相手はいないんでしょうか。このサイトで質問をくりかえことが役に立ってる感じがしないですね。勉強のやり方を変えたほうが良いのでは?と思うけど、具体的なアドバイスはできませんしねえ。。。
carnage0216

2018/02/19 05:50

そうですか。 これでも前進してC言語を勉強できているのですが...。
carnage0216

2018/02/19 05:53

ちなみに、レジスタレベルの理解ではCPUへの理解が浅いとの事ですが、CPUへの理解を深めるにはレジスタ以外に何を行えば良いのでしょうか? 教えて頂けるとありがたいです。
rubato6809

2018/02/19 22:22

前進しているのであれば結構。余計なお世話だったかもね。 > レジスタレベルの理解ではCPUへの理解が浅いとの事ですが、 いいえ、そういうつもりで言ったのではありません。アセンブリ言語を扱う条件として ・CPU内部にどんなレジスタがあるか という条件を挙げました。ターゲットCPUのレジスタを知らずにアセンブリ言語が分かるはずがない、と言ったのです。貴方はまだCPUのレジスタをちゃんと知らない、だからアセンブリ言語も扱えない、そういうレベルなのだろうと思ったからです。早とちりかもしれないけど。 > CPUへの理解を深めるにはレジスタ以外に何を行えば良いのでしょうか? それに答える前に、お聞きしたい。 CPUのレジスタは知っているのですか? アセンブリ言語の経験はいかほど?プログラムを読めますか?アセンブリ言語を書いた、或いはコンパイラが生成したコードに手を入れた事はありますか?
carnage0216

2018/02/20 17:51

余計なお世話などではありません。返信いただけて嬉しいです。おっしゃる通り、使用しているCPUにどのようなレジスタが含まれているか理解できていません。データシートやサンプルプログラムをアセンブリ言語で出力させてどのような時にあるレジスタを使うのかなどを見ております。 私が今のところアセンブリ言語を用いて取り組めた物はPICマイコンを用いてLチカとコイルガンをサイトをもとに自作した程度です。 以上を作成してからブランクがあるため今からPICマイコンのアセンブリ言語を読むのに少し苦労するかもしれません。なので、読める、読めないで言えば、読めないに入るかもしれません。 また、pcで簡単なhello wordプログラムをアセンブリ言語に変換してコードを手に入れた事はありますが、CPUでのアセンブリ言語は全く初めてであるため、入門からグダグダです。
guest

0

ファイル操作などの

それはOSのAPIを使うかないんだからアセンブリで直書きする必要が皆無

C言語において勉強中なのですが、CPUなどを使いこなすのにアセンブリ言語を勉強している人などがいるなどの記述があったので気になりました。

SIMD化のことかな?でもそれでもintrinsic使うからアセンブリで頑張るのは過去の話じゃないかなと。

ただし、じゃあCを使えばそのへん意識しなくていいかといえば(高速化のためには)全くそんなことはないので、まあそういうことですね。

投稿2018/02/17 16:28

yumetodo

総合スコア5850

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問