数式が読み込まれない場合は1回再読み込みしてみてください。まとめシリーズこんにちは、ももやまです。今回からはしばらくアセンブラ(アセンブリ言語)についてまとめていきたいと思います。※正式にはアセンブラは「アセンブリ言語で書かれたものを実行できる形(機械語)に変換するソフトウェア」のことですが、アセンブリ言語のことをアセンブラと呼ぶことが多いため、今回の記事ではアセンブリ言語のことをアセンブラと呼びたいと思います*1。この記事を見ている人で、将来アセンブラで食っていくような人は少ないかもしれません。アセンブラを学ぶことでCPU(プロセッサ)、レジスタなどのハードウェアがどのように動作しているかを体感することができます。アセンブラを学ぶことでコンピュータの気持ち(姿?)を少し理解することができるのです!ということで、まずはアセンブラを学ぶ前に知っておくべき9つの知識を今回は説明していきたいと思います。ゼロ拡張10.さいごに0.アセンブラとはCPUが直接実行できる言語は機械語のみです。(皆さんがおそらく書いたことであるだろうC言語、Java、Python、Rubyは、そのまま実行することはできず、コンパイラやインタプリタを使って機械語に直してあげなければなりません*2。)しかし、機械語は2進数、つまり0,1だけで書かれているので普通の人間には理解することができません。人間が機械語を書くなんてもってのほかです。そこで機械語で記された命令を人間でもわかるように名前をつけたものをアセンブラと呼びます。機械語に名前をつけているだけなので、アセンブラは機械語と1対1対応します。機械語と1対1対応しているアセンブラを学ぶことは、CPU依存の機械語も学ぶことと同様です。機械語ではなく、アセンブラを学ぶことでもコンピュータのハードウェアについて学ぶことができます。命令実行時のCPUの動き2進数から10進数への相互変換2進数から16進数への相互変換2進数での足し算・掛け算2の補数を用いた負の数の表現ビット演算(AND・OR・XOR)論理シフト・算術シフトの違い符号拡張・ゼロ拡張の違いを簡単にですが説明していきたいと思います。機械語はCPU依存なので、1対1対応しているアセンブラもCPU依存となります。CPUによってアセンブラの書き方(文法)が変わってきます。II*3」などがあります。部品1:プログラムカウンタ(プログラムレジスタ)次に実行される命令のアドレスを保持するレジスタです。命令フェッチ*4をするたびに一定数増加します。プログラムカウンタの1回あたりの増加量は命令の長さに比例します。命令の長さが2バイト(16ビット)であれば2ずつ増加し、4バイト(32ビット)であれば4ずつ増加します。部品2:命令レジスタ現在実行している命令の内容(コード)を一時的に格納する部品です。部品3:フラグレジスタ(ステータスレジスタ)各種フラグが立っているかどうかを格納するレジスタです。プロセッサによってはフラグレジスタがないこともあります。Flag)の3つがあるので簡単に紹介したいと思います。SF:サインフラグACC(アキュームレータ)の値、つまり演算結果が負であれば「1」、そうでなければ「0」が立つフラグですZF:ゼロフラグACC(アキュームレータ)の値(演算結果)が0であれば「1」、0以外なら「0」がたつフラグです。OF:オーバーフローフラグACC(アキュームレータ)の値(計算結果)がオーバーフローしたときに「1」となるフラグです。部品4:汎用レジスタ特別な用途を持たないただのレジスタです。演算の結果や読みだしたデータを一時的に格納するときに使われます。部品5:デコーダ命令レジスタに保存した命令を解読します。練習問題で確認してみましょう。(2)の処理をする部品の名称として正しいものを選びなさい。3(プログラムカウンタと命令レジスタは間違えやすいので注意!!)2.命令実行時のCPUの動きプロセッサの命令実行の4ステップも確認しておきましょう。命令実行時、CPUは命令フェッチ(メモリ→CPUへ命令読み込み)命令解読(読み込んだ命令をデコーダで解読)命令実行(解読された命令の実行、ALUで演算)結果の格納(演算結果をメモリ・レジスタに格納)の4ステップをひたすら繰り返します。DMA(転送)CPUを経由せずにメインメモリと入出力装置間のデータ転送を制御することをDMA(転送)と呼びます。DMAを用いることで、データ転送中にも(CPUを使う)別の処理を行うことができます。(2)の問いに答えなさい。(1)命令が実行されるときのCPUの動きになるように1〜4を並び替えなさい命令を解読するメインメモリからCPUに命令を読み込む結果をレジスタに格納する命令を実行する(2)DMAの説明として、適切なものを1つ選びなさい。午前問13]ア;CPUが磁気ディスクと主記憶とのデータの受渡しを行う転送方式である。イ:主記憶の入出力専用アドレス空間に入出力装置のレジスタを割り当てる方式である。ウ:専用の制御回路が入出力装置や主記憶などの間のデータ転送を行う方式である。エ:複数の命令の実行ステージを部分的にオーバラップさせて同時に処理し,全体としての処理時間を短くする方式である。ウ(アはDMAを使わない通常の処理形式の説明)ここまでの記事を見てもう少し復習しておきたいなと思う人はこちらの記事をご覧ください。www.momoyama-usagi.com3.2進数と10進数への相互変換アセンブラでは2進数についての知識を頻繁に使用します。ここからは2進数の知識について簡単にですが復習していきたいと思います。2進数と10進数の相互変換ができるかを確認しましょう。(4)の10進数を2進数に直しなさい。ように最初に0bをつけることが多いです。1の数が多くなると見にくいですよね。そこで、下のように4桁を1区切りで表記できる16進数を使うことで2進数で桁数が多くなっても、少ない桁数で見やすくなります。16進数では10〜15を1文字で表現できるようにするために、それぞれの数字をアルファベットで表現します。具体的には10をA、11をB、12をC、13をD、14をE、15をFとしています。練習4(1)の2進数を16進数に、(2)の16進数を2進数に直しなさい。ように最後にhをつけるか、0xD69Fのように最初に0xをつけることが多いです。5.2進数の足し算・掛け算2進数の足し算(引き算)、掛け算も10進数と同じようにできちゃいます。練習問題で確認しましょう。練習5つぎの2進数同士の計算をしなさい。0x49解答5(1)下の図のように筆算でやることを強くおすすめします。2進数は2で繰り上がりが発生するので注意しましょう。(2)掛け算も10進数と同じように計算できます。足す回数が増えるので計算ミスなどに気をつけましょう。(3)16進数の場合は16で繰り上がりで発生します。2進数よりも桁数が少ないので計算はしやすいかと思います。引き算を足し算と同じように処理できるように作られたのが2の補数です。アセンブラでも2の補数の知識が必要なので、2の補数を使って負の数を作り出す方法を確認しておきましょう。練習6「-100」を8ビットの2の補数を用いて表現しなさい。8ビットの2の補数表現で表せる数の範囲を10進数で答えなさい。解答6まず、作りたい数の絶対値(今回は-100の絶対値である100)を2進数で表現します。100を2進数で表現すると、01100100(2進数)となりますね。ここから2の補数を作るのですが作り方は2パターンあるので両方のパターンを紹介します。パターン1:ビットを反転させて1を加算2の補数は、最初に作った絶対値のビット(0,1)を反転し、1を加算することで求めることができます。よって「-100」を8ビットの2の補数で表すと「0b10011100」となります。減算して求めるビット数+1の位が1、残りが0の2進数(100......00)から絶対値(今回の場合は100を2進数にしたもの)を引くことで求めることもできます。0000から絶対値(0b01100100)を引いて求めます。2進数の引き算では「1つ上の桁から借りる」動作が多くなるので計算ミスに気をつけましょう。個の数を表すことができます。256個を正の数と負の数で表現するため、正の数(と0)で128個、負の数で128個の数を表せます。128個を表すことができます。-128〜127以下が表せます。なることは必ず覚えておきましょう。7.ビットごとの論理演算(OR・AND・XOR)2進数のそれぞれのビットごとに対し、OR、AND、XOR演算を行うことができます。練習問題で確認していきましょう。練習72つの自然数「230」、「119」を8ビットの2進数(補数表現ではない)で考え、ビットごとにOR、AND、XOR演算を行った結果を10進数で答えなさい。解答7「230」を2進数に直すと「0b11100110」、「119」を2進数に直すと「01110111b」となる。OR演算それぞれのビットごとにOR演算(片方でも1なら結果が1)を行う。すると、「0b11110111」となり、10進数に直すと247になります。AND演算それぞれのビットごとにAND演算(両方が1のときだけ1)を行います。すると、「0b01100110」となり、10進数に直すと102になります。XOR演算それぞれのビットごとにXOR演算(両方が1のときだけ1)を行います。すると、「0b10010001」となり、10進数に直すと145になります。排他的論理和(XOR)は、特定のビットを反転させるときに使われます。元の数と反転させたいビットを1とした数の排他的論理和を取ることで特定のビットを反転させることができます。1001の偶数番目の桁のビットを反転させたいときは、元の数1001と反転させたいビットを1とした0101の排他的論理和を取ります(答え:1100)。アセンブラでは、算術演算(足し算・引き算)、論理演算を用いた処理がよく出てきます。下の練習問題で少し確認してみましょう。(2)の処理を「2進数の加算」・「2進数の論理演算」だけで行うためにはどのような処理をすればいいかを考えてみましょう。解答8(1)偶数であれば、2進数において1の位は必ず0、奇数であれば1の位は必ず1となります。(どんな偶数でも2進数に直すと1の位は0、どんな奇数でも2進数に直すと1の位は1となります。疑う人は何個か実際に試してみましょう。)なので、1の位以外をすべて消し、1の位だけを残すことで偶数か奇数かを判定できます。そのため、「元の数」と「1」の論理積を取ることで1の位を残すことができます。(2進数の1は、1の位以外はすべて0なので「元の数」と論理積を取ると1の位以外がきれいに消滅する)処理例:24は偶数か判定する→24の2進数は11000、11000と1の論理積は0。(2)ある数の2の補数を取るためには、元の数のビットを反転し、1を加算することで求めることができます。元の数のビットをすべてを反転させる動作、つまり「元の数」と「元の数と同じ桁数だけ1になっている数」の排他的論理和をとり、最後に1を足すことで2の補数を取ることができます。0101と1111の排他的論理和は1010、1を足して1011。よって2の補数を取ると1011となる。倍にすることができます。このように桁をシフトさせて値を変えることをシフト演算と呼びます。倍することができます。シフトにより空いた桁には0を挿入します。2ビット左シフトさせると、値は4倍になります。左側の溢れた桁は消滅するので注意してください。倍することができます。シフトにより空いた桁には0を挿入します。2ビット右シフトさせると、値は1/4倍になります。(小数点以下は切り捨てられます)なお、右側の溢れた桁は消滅するので注意してください。(左側だけでなく、右側の桁が消えた場合でもオーバーフローとなるので注意してください。)算術シフト演算2の補数の場合、そのままシフト演算を行うと符号が変わってしまい、思った結果が得られません。そのため、普通の2進数と正負を考える2進数(補数表現)ではシフトの方法が少し変える必要があります。算術シフト演算は、(2の補数表現で)正負を考えた2進数のシフト演算で使います。倍することができます。シフトにより空いた桁には0を挿入します。2ビット左シフトさせると、値は4倍になります。論理シフトと同じように左側の溢れた桁は消滅するので注意してください。(消えた桁によってはオーバーフローになる可能性あり)ここで、最上位ビットは符号ビットであるところに注意が必要です。下のように見た目ではオーバーフローが起こっていないような場合でも、最上位ビットが変わることによりオーバーフローが発生することがあります。(2の補数で計算できる範囲を確認しましょう。倍することができます。論理ビットと同じように右シフトを行うと、正負が変わってしまい正しく結果を求めることができません。そこで元の2進数の符号ビットによって空いた桁に挿入する数を変えることで正しく算術右シフトを行うことができます。2ビット右シフトさせると、値は1/4倍になります。(小数点以下は切り捨てられます。負の数の切り捨てに注意してください*5。)もちろん下のような元の符号ビットが0の2進数であれば、空いた位には0が挿入されます。右側の溢れた桁は消滅するので注意してください。(論理シフトと同じく消えた桁によってはオーバーフローになる可能性あり)9.符号拡張・ゼロ拡張の違い符号拡張、ゼロ拡張の違いについても簡単に確認しておきましょう。符号拡張は2の補数表現を用いた計算をする場合に必要です。下のようなビット数が異なる2進数の計算をすると、計算結果が思った通りにならないことがあります。そのため、2の補数表現を用いた2進数の計算をする際には必ず2つのビット数をあわせてから計算を行う必要があります。このビット数をあわせるために符号拡張を使います。符号拡張では、左側に追加したビットに元の桁の符号ビットと同じ数字を追加します。4ビットの2進数0b1001を8ビットに符号拡張することを考えましょう。符号ビットは1(つまり負)なので、追加する4ビットにすべて1を追加すると、0b11111001となります。先程紹介した計算も、符号拡張をすることで正しく計算を行うことができます。ゼロ拡張ゼロ拡張は2の補数表現を用いない(つまり自然数の)2進数計算をする場合に使います。追加する桁数分だけ左側に0をつけるだけでゼロ拡張の完了です。ほら、簡単でしょ??10.さいごに今回はアセンブラを学ぶ前に確認すべき9つの知識について簡単にですが説明しました。今回紹介した9個の知識(特に2進数関連)はアセンブラを学ぶ上で非常に大切なので必ず覚えておきましょう。2進数関連の処理が不安な人向けに、関連の記事を2つほど用意しているのでもう少し復習したい人はぜひご覧ください。2進数の基礎1(絶対値表現、負の数が出てこない処理)www.momoyama-usagi.com2進数の基礎2(2の補数表現、負の数も出てくる処理)www.momoyama-usagi.com次回からはいよいよアセンブラの命令(mipsアーキテクチャを使いたいとおもいます)について2回にわけて説明していきたいと思います。アセンブリ言語のことをアセンブラと呼んでいます。Rubyのようなスクリプト言語であればインタプリタを使って機械語に直します。*3:試験でも使われる架空のアセンブラ*4:どんな命令を実行するのかを聞くこと*5:例えば-7.25であれば-7にするのではなく、-7.25以下の中で最も大きい整数である-8を取ります。システムオートマトンPrologCLOSEサイト内検索を行います。はてなブログPro数学と情報が得意な大学生です。累計:リアルタイム現在の閲覧者数:。