質問: アセンブリ言語を使っている方にお聞きしたいのですが、使用している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の構造を詳しく知らないとプログラム自体組めない様にも思えます。 また、質問とは真逆にアセンブリプログラムからわからない情報は何かありますか? 編集後で申し訳ありませんがどうかよろしくお願いいたします。
回答: こんにちは。 > > C言語において勉強中なのですが、CPUなどを使いこなすのにアセンブリ言語を勉強している人などがいるなどの記述があったので気になりました。 > > > アセンブラでギチギチにハードウェアを制御すれば最大限の性能を引き出せますが、その方法で大規模なプログラムを開発することはあまり現実的ではありません。生産性が低すぎてお金がかかりすぎるのです。そのため、そこまでやるのは処理速度が最重要なごく一部の分野の狭い範囲に限定されます。 多くの人は、そのようにして開発されたデバイスドライバやライブラリを用いて、それなりの速度で動作するプログラムを開発し、生産性を確保します。 この速度と生産性のトレードオフは対象のプログラムで大きく振れます。生産性命の分野もあれば速度命の分野もあります。C言語は速度命に近い分野のプログラムで良く使われます。ですので、ハードウェアの特性を把握していれば居るほど有利になる(より高速なプログラムを開発できる)というわけです。 そのためにアセンブラを勉強することはかなりお薦めです。 【質問の追記への回答】 > > だとしたら、何をもとに使っているCPUの内部構造を把握したのでしょうか? > > > 最初はやはりアセンブラの入門書で学習するのが良いように感じます。情報処理技術者試験のCASLなどなら入門書もあるように思います。 実際のハードウェアを制御してみたいのであれば、ATEMLのAVRやPIC)ならばハードウェアも廉価ですし、情報も豊富です。(個人的には構造が素直なAVRがお勧めです。) > > 個人的にはアセンブリ言語はCPUに依存するため使うCPUの構造を詳しく知らないとプログラム自体組めない様にも思えます。 > > > その通りです。しかし、いきなりPCのCPUから始めるのは難しすぎるのでお勧めではありません。 私自身はまだCPUが単純だった頃からこの分野に興味を持ちましたので、上記のAVRマイコンよりも更に簡単なマイコンから入りました。その流れ自体は正解だったと思います。 まずは、基本のメモリやレジスタの仕組みをマスターすることが重要と思います。その辺りを把握しているのとしていないのとでは、C言語で書けるプログラムの質が結構変わると思います。