アセンブリ言語とは?

このQ&Aのポイント
  • アセンブリ言語とは、人間が機械語を直接扱うのではなく、命令単位に区切られた英単語を使用してプログラムを書くための言語です。
  • アセンブリ言語を使うことで、機械語の直接書き込みでは理解しづらいプログラム構造を抽象化し、人間にとってより読み書きしやすくなります。
  • アセンブリ言語は機械語に対応した1対1の命令を持ち、プログラムを機械語に変換することでCPUが実行できるようになります。
回答を見る
  • ベストアンサー

アセンブリ言語について。

>2進数の羅列では人間にはあまりに読み書きしにくいからです。 >それを命令単位に区切って、英単語を元にした名前を与えたのが、 >アセンブリ言語です。 ニーモニックとは、その命令の名前の事です。 簡潔に要点がまとまっている、すばらしい説明ですね。その通りです。 これで理解できないなら、追加の説明のしようがありません。 (なお、このように、他人の発言は引用符を付けて引用すると、わかりやすくなります。是非そうしてください。) まあ具体例を挙げるならこんな感じ。 (機械語データ) (アセンブリ言語) b8 57 61 6b 61 mov $0x616b6157,%eax 53 push %ebx 50 push %eax ba 04 00 00 00 mov $0x4,%edx bb 01 00 00 00 mov $0x1,%ebx b8 04 00 00 00 mov $0x4,%eax 89 e1 mov %esp,%ecx cd 80 int $0x80 58 pop %eax 31 c0 xor %eax,%eax 5b pop %ebx c3 ret 人間がCPUを直接動かすプログラムを書こうとするとき、アセンブリ言語を使って書きます(右側の部分)。 mov $0x616b6157,%eax push %ebx push %eax mov $0x4,%edx mov $0x1,%ebx mov $0x4,%eax mov %esp,%ecx int $0x80 pop %eax xor %eax,%eax pop %ebx ret そしてこれをアセンブルすると、1対1対応した機械語のデータ列が出来ます。 それが b8 57 61 6b 61 53 50 ba 04 00 00 00 bb 01 00 00 00 b8 04 00 00 00 89 e1 cd 80 58 31 c0 5b c3 この部分。 機械語には改行なんてありませんから、実際は一連の b8 57 61 6b 61 53 50 ba 04 00 00 00 bb 01 00 00 00 b8 04 00 00 00 89 e1 cd 80 58 31 c0 5b c3 と言うデータ列になります。 これをCPUが実行していきます。 相当熟練した人で無ければ、このデータ列を見るだけでプログラム構造を理解する、というわけに行きません。 なので、人間が機械語レベルでプログラミングする際には、アセンブリ言語を使います。 ※この回答のプログラムはこちらから引用しました。 >31バイトでつくるアセンブラプログラミング アセンブラ短歌の世界 >https://book.mynavi.jp/support/pc/4946/c01_assembra.pdf で、機械語データは、なぜ、0と 1だけではないのでしょうか?教えていただけないでしょうか?すみません。

質問者が選んだベストアンサー

  • ベストアンサー
  • A1200hd40
  • ベストアンサー率52% (337/648)
回答No.7

>機械語データは、なぜ、0と 1だけではないのでしょうか? 実際は2進データであっても、「ヒト」にとっては「見づらい」ので16進数や8進数に変換して、圧縮表記します。 人間の目は機械のようにいきませんから、紛らわしい表記だと、普通に間違いが出ます。 64bitの2進データは、64文字使います。 64個の0/1を、きちんと順番を間違えずに記述するのは困難です。 (当たり前ですが、間違うと期待通りに動きません) 16bitなら4桁、32bitなら8桁、64bitなら16桁の16進で事足ります。 (ちなみに8bitで1Byteです) その昔は、雑誌に機械語ダンプリストが載ることも在ったのですよ。 マシン語モニタって、恐ろしく単純なプログラム使って打ち込んでくやつ。 こういう時にバイナリ(2進)表記だと、ページ数が相当ムダになりますよね。 それから0/1のビット列表記を入力することを考えてみてください。 そのうち目がチカチカしてきて、桁数数えるのにも疲れてしまい、頭もおかしくなってきます。 16進数は、0~9までの数字と、a~fまでのアルファベットで表現されます。 16進数の0fは10進数では15です。 16進の10は、10進では16です。 16進数等の表記に直すのは、「ヒト」のため、少しでも小さく表記して、なおかつ、間違わないようにするためです。

zasx1098
質問者

補足

16bitなら4桁、32bitなら8桁、64bitなら16桁の16進で事足ります。 (ちなみに8bitで1Byteです) なぜ、こうなるのでしょうか?教えていただけないでしょうか?すみません。

その他の回答 (8)

  • ballville
  • ベストアンサー率47% (233/487)
回答No.9

>相当熟練した人で無ければ、このデータ列を見るだけでプログラム構造を理解する、というわけに行きません 8ビットパソコン時代のキッズたちの多くは、普通にそういうことをやっていたんですが。 お小遣いでアセンブラを入手することは簡単ではないので、 ハンドアセンブルといって、方眼紙にニーモニックやオペランドを書き込んで、ニーモニック表と首っ引きで、人間アセンブラをやっていました。 そうこうするうちに、自然とニーモニックと機械語の対応を覚えたものです。

  • chachaboxx
  • ベストアンサー率23% (412/1777)
回答No.8

16進表記も2進表記も実行内容は同じです。 人が読みやすく理解しやすい表記に変換するだけのことであって、拘る本質はそこにはありません。 列挙された単純命令をいかに効率よく早く処理するかはどちらかというとコンパイラーの仕事になりますが、そもそもそんな処理が本当に必要なのかどうかは、人にしか判断できませんが、AIが進化すればそうでもないかもしれませんね。

  • hahaha8635
  • ベストアンサー率22% (800/3609)
回答No.6

スイッチ を 入れるか 入れないかです まず トランジスタ から始まります https://detail-infomation.com/bipolar-transistor/ 2種類あるのですが 理解しやすいNPN型だけ理解してください 3本あしがでていて Cにプラス-Eにマイナス につながっています 通常は電気が流れず ベースに電気を流すと C-E間に電気が流れます 電気を流していないとき を 0  電気を流しているとき  を 1 とします それを組み合わせて 論理回路 というのが作られます http://www.gxk.jp/elec/musen/1ama/H14/html/H1404A08_.html A と B という信号を D という答えにして返す回路です これらをまた組み合わせて 加算器 https://ja.wikipedia.org/wiki/%E5%8A%A0%E7%AE%97%E5%99%A8 などの 四則計算機 や フリップフロップ https://ja.wikipedia.org/wiki/%E3%83%95%E3%83%AA%E3%83%83%E3%83%97%E3%83%95%E3%83%AD%E3%83%83%E3%83%97 などの メモリが考え出されました 電気の流れで計算ができるようにしました 1ビット 一つの電気信号だけでは わかりにくいということで 4ビット1-10を表せる ものをひとまとまり にして 考え出され 4ビットに それぞれ 命令の意味を乗せ CPU4004になりました http://www.st.rim.or.jp/~nkomatsu/intel4bit/i4004.html やがてそれは 8008 8086 ・・・ となり 現在のCPUになります なので すべては電気を流しているか流していないをを クロックベースで処理していくので 0or1なのです

  • _kappe_
  • ベストアンサー率68% (1522/2216)
回答No.5

>機械語データは、なぜ、0と 1だけではないのでしょうか? 2進数とか16進数について調べてください。質問文に引用されている機械語データは16進数で書かれています。 2進数は数字の各桁を0と1の2種類だけで表します。10進数の5は2進数だと101、10進数の14は2進数だと1110です。 2進数だと桁数が大きくなって読みづらいので、代わりに16進数(各桁を0〜9とA〜Fの16種類で表す、アルファベット部分は大文字でも小文字でも意味は違わない)を使うことがよくあります。16は2の4乗であるため、16進数の1桁でちょうど2進数の4桁を表せるからです。たとえば10進数の154を2進数で表すと10011010の8桁ですが、これを4桁ずつに1001 1010と区切って16進数に直せば9Aの2桁になります。2進数と16進数の間の変換は16パターンを覚えればいいだけなので簡単です。 質問文に引用されている機械語データの最後にあるc3は2進数に書き直せば11000011です。

  • t_ohta
  • ベストアンサー率38% (5076/13261)
回答No.4

> で、機械語データは、なぜ、0と 1だけではないのでしょうか?教えていただけないでしょうか?すみません。 CPUは電気がONかOFFかの2つの状態の違いで動作しています。 その電気がONかOFFかを記録上人間が判りやすく表現するために0と1と表現したからです。 これを二進数と呼んでいます。 ↓これを読むとCPUの仕組みが理解できると思いますよ https://books.rakuten.co.jp/rb/1598842/

  • chie65535
  • ベストアンサー率43% (8519/19365)
回答No.3

>で、機械語データは、なぜ、0と 1だけではないのでしょうか? コンピュータ内部では「オフ」と「オン」、「ローレベル」と「ハイレベル」つまり「0」と「1」だけです。 例えば mov $0x616b6157,%eax は 1011100001010111011000010110101101100001 というオンとオフの羅列でメモリに記憶されます。 でも、0と1の羅列では「人間が見て判りにくい」ので、16進数で表記する事にしました。 人間が見て判りやすいくする為だけに、以下のように2進数4桁(4ビット)を16進数1桁で表したのです。 0000 ⇒ 0 0001 ⇒ 1 0010 ⇒ 2 0011 ⇒ 3 0100 ⇒ 4 0101 ⇒ 5 0110 ⇒ 6 0111 ⇒ 7 1000 ⇒ 8 1001 ⇒ 9 1010 ⇒ A 1011 ⇒ B 1100 ⇒ C 1101 ⇒ D 1110 ⇒ E 1111 ⇒ F そして、16進数2桁分、つまり「8ビット分」を「1バイト」とする事にしました。これも「人間が見て判りやすくする為」です。 なので 1011100001010111011000010110101101100001 というオンオフの羅列を、2進数として扱い、その2進数を16進数で表せば b8 57 61 6b 61 という5バイトになる訳です。 この「16進数で表記する」のは「人間が判りやすくするため」なので、コンピュータそのものには何の意味もありません。 では、何のために「人間が判りやすくするため」なのかと言うと、昔のコンピュータでは、アセンブラが生成した機械語コードを「人間が手作業でメモリに書き込みする必要があったから」です。 「人間が手作業でメモリに書き込みする」時に、2進数の羅列のままでは、1桁ズレたり、1桁見落としたり、ミスが増えます。 それに、0と1だけでは「紙に書いた時に、スペースを食い過ぎる」という理由もあります。 なので、ミスを減らすため「2進数8個分、つまり、16進数2桁分を、16進表記のままメモリに書き込む」ように工夫をしました。 その為、アセンブラでコード生成する時に「生成したコードを16進表記で併記する」ようになったのです。 生成したコードを直接にコンピュータのメモリに格納して、その場で実行するだけなら、16進表記でコードを表記する必要はありません。 表記するのは、あくまでも「人間が見て、判りやすくするため」です。コンピュータそのものにはまったく不必要なのです。 アセンブラも、高級言語も、16進数表記も、すべて「人間が見た時に、理解しやすいようにするため」なのです。 コンピュータ内部では、人間に理解しやすくする必要は無いので「オフとオンの羅列」だけで、何の問題もありません。 本当は、オフとオン、ローとハイの羅列だけで、何の問題もないのです。

  • bardfish
  • ベストアンサー率28% (5029/17765)
回答No.2

>機械語データは、なぜ、0と 1だけではないのでしょうか? 0と1だけですよ。 2進数って聞いたことありますか? 2進数だと人間が理解しやすい形式(文字のことですね)にしたときに長大な字数になってしまうので1桁の2進数をビットと呼ぶことにして、ビットをある程度まとめて8進数とか16進数に「置き換え」たものを使用しているのが一般的です。 複数桁の2進数を10進数や16進数に直す計算方法はちょっと調べればすぐ見つかるので説明は省きます。パソコンやスマホの電卓アプリの中には変換する機能が備わったものもあります。個人的には関数電卓の方が手軽で使いやすいです。 ついでに、文字コード(ANKとかASCIIコード、JISやS-JIS)も通常は16進表記が一般的です。2進数で表記されたら無駄に長ったらしくなってプログラムのコードとして埋め込む場合も無駄でミスしやすい。 と、ここまで書いていて気づいたのですが・・・ 2進数で表記するとミスしやすく、ミスが発覚してもミスした場所を見つけにくくなってしまうというのもありますね。 基本的には「人間の都合に合わせて変化してきた」のが理由だと思います。

  • wormhole
  • ベストアンサー率28% (1619/5654)
回答No.1

>機械語データは、なぜ、0と 1だけではないのでしょうか? 0と1だけですよ。 それを4こ、8こ、16こ、32こ、64ことまとめて扱って表現できる幅を増やしてるだけで。 ふだん扱ってる数字だって0~9の10個しかないけど、それを2こ、3こ組み合わせることで10とか100とか表現してるでしょ? と書きましたけど、今までの経緯から、あなたが正直理解できる気はしていません。 たぶん理解するには色々基礎知識が足りてないです。

関連するQ&A

  • アセンブリ言語について。

    これが何をしているのか教えていただけないでしょうか?すみません。 これの事です。 (機械語データ) (アセンブリ言語) b8 57 61 6b 61 mov $0x616b6157,%eax 53 push %ebx 50 push %eax ba 04 00 00 00 mov $0x4,%edx bb 01 00 00 00 mov $0x1,%ebx b8 04 00 00 00 mov $0x4,%eax 89 e1 mov %esp,%ecx cd 80 int $0x80 58 pop %eax 31 c0 xor %eax,%eax 5b pop %ebx c3 ret

  • 機械語とアセンブリ言語について。

    (機械語データ) (アセンブリ言語) b8 57 61 6b 61 mov $0x616b6157,%eax 53 push %ebx 50 push %eax ba 04 00 00 00 mov $0x4,%edx bb 01 00 00 00 mov $0x1,%ebx b8 04 00 00 00 mov $0x4,%eax 89 e1 mov %esp,%ecx cd 80 int $0x80 58 pop %eax 31 c0 xor %eax,%eax 5b pop %ebx c3 ret こちらのアセンブリ言語の命令がわかるおすすめの書籍を知らないでしょうか? 教えていただけないでしょうか?すみません。

  • 機械語とアセンブリ言語について。

    (機械語データ) (アセンブリ言語) b8 57 61 6b 61 mov $0x616b6157,%eax 53 push %ebx 50 push %eax ba 04 00 00 00 mov $0x4,%edx bb 01 00 00 00 mov $0x1,%ebx b8 04 00 00 00 mov $0x4,%eax 89 e1 mov %esp,%ecx cd 80 int $0x80 58 pop %eax 31 c0 xor %eax,%eax 5b pop %ebx c3 ret で、右側のアセンブリ言語のニーモニックとオペランドについて解説していただけないでしょうか?すみません。

  • 機械語に直すことについて。

    (機械語データ) (アセンブリ言語) b8 57 61 6b 61 mov $0x616b6157,%eax 53 push %ebx 50 push %eax ba 04 00 00 00 mov $0x4,%edx bb 01 00 00 00 mov $0x1,%ebx b8 04 00 00 00 mov $0x4,%eax 89 e1 mov %esp,%ecx cd 80 int $0x80 58 pop %eax 31 c0 xor %eax,%eax 5b pop %ebx c3 ret これのintと movとxor の機械語が分かりません。後、retの機械語が、farなのかnearなのかも分かりません。教えていただけないでしょうか?すみません。

  • アセンブリ言語の質問です

    「 100人分の試験点数がある。 一人分のデータは32bit 符号無し整数でそれが連続して格納されている.先頭のアドレスがEAXで与えられる時,全員の点数の合計をEAXに入れて戻るようなサブルーチンをアセンブリ言語で書きなさい。 • loop unrollingを使用して,ループ内容を4倍に展開して,条件分岐数を減らすこと • 他のレジスタの値は保存すること • 合計点はEAXレジスタに十分納まるものとする。 • 次のような命令を使ってよい。 ADD EAX, [EBX] 」 というような問題が出て自分で解答を作ってみたのですがこれでよいのでしょうか?詳しい方ご検討よろしくお願いいたします。 PUSH EBX(EBXをスタックにおいておく) PUSH ECX(ECXをスタックにおいておく) MOV ECX 25(ECXに25を代入。4回の操作を25回すれば100回になるからである。) label0:ADD EAX [EAX] ([EAX]をEAXに加算) ADD EAX [EAX+1]([EAX+1]をEAXに加算) ADD EAX [EAX+2]([EAX+2]をEAXに加算) ADD EAX [EAX+3]([EAX+3]をEAXに加算) MOV [EAX] [EAX+4]([EAX]を[EAX+4]に移動させる) EBX=EBX+1 (EBXはこのループを何回やったか、という数) CMP ECX EBX(25とEBXを比べる) JNZ:label0(比べてEBXが25になってないならば繰り返す。25になったら終了。) POP EBX(EBXをスタックから戻す) POP ECX(EBXをスタックから戻す)

  • アセンブリ言語の宿題がわかりません。

    爆弾を解除するプログラムです。exeファイルしか与えられていません。 phase1から5まであり、それぞれにインプットを求められ、正しいインプット(解除コード)を入力すると解除できます。 間違ったコードを入力すると爆発してしまいます。1,2は解けましたが、3で躓きました。objdumpしてみて、あるstring(恐らくglobal定数)と同じインプットをすれば解除できると踏んだのですが、どうしてもその特定のstringがわかりません。 以下にobjdumpした内の一部を載せておきました。都合上最小限のコードだけ載せざるを得ませんでしたので、 下記URLに、exeファイル、逆アセンブルファイル、phase1,2のanswerをアップロードしております。お時間があれば是非ご協力をお願いします。 環境 OS:ubuntu 9.04 デバッガ:Gnu DeBugger 08048424 <_IO_getc@plt>: 8048424: ff 25 10 a0 04 08 jmp *0x804a010 804842a: 68 20 00 00 00 push $0x20 804842f: e9 a0 ff ff ff jmp 80483d4 <_init+0x18> 08048723 <phase_3_of_5>: 8048723: 55 push %ebp 8048724: 89 e5 mov %esp,%ebp 8048726: 57 push %edi 8048727: 56 push %esi 8048728: 53 push %ebx 8048729: 83 ec 1c sub $0x1c,%esp 804872c: a1 30 a0 04 08 mov 0x804a030,%eax 8048731: 89 04 24 mov %eax,(%esp) 8048734: e8 eb fc ff ff call 8048424 <_IO_getc@plt> 8048739: bb 00 00 00 00 mov $0x0,%ebx 804873e: 8d 75 e6 lea -0x1a(%ebp),%esi 8048741: eb 04 jmp 8048747 <phase_3_of_5+0x24> 8048743: 88 44 33 ff mov %al,-0x1(%ebx,%esi,1) 8048747: a1 30 a0 04 08 mov 0x804a030,%eax 804874c: 89 04 24 mov %eax,(%esp) 804874f: e8 d0 fc ff ff call 8048424 <_IO_getc@plt> 8048754: 83 f8 0a cmp $0xa,%eax 8048757: 74 06 je 804875f <phase_3_of_5+0x3c> 8048759: 43 inc %ebx 804875a: 83 fb 0f cmp $0xf,%ebx 804875d: 75 e4 jne 8048743 <phase_3_of_5+0x20> 804875f: c6 45 f3 00 movb $0x0,-0xd(%ebp) 8048763: 8d 75 e6 lea -0x1a(%ebp),%esi 8048766: bf e4 8b 04 08 mov $0x8048be4,%edi 804876b: b9 0d 00 00 00 mov $0xd,%ecx 8048770: fc cld 8048771: f3 a6 repz cmpsb %es:(%edi),%ds:(%esi) 8048773: 0f 97 c2 seta %dl 8048776: 0f 92 c0 setb %al 8048779: 38 c2 cmp %al,%dl 804877b: 74 0c je 8048789 <phase_3_of_5+0x66> 804877d: c7 04 24 03 00 00 00 movl $0x3,(%esp) 8048784: e8 31 fe ff ff call 80485ba <explode> 8048789: 83 c4 1c add $0x1c,%esp 804878c: 5b pop %ebx 804878d: 5e pop %esi 804878e: 5f pop %edi 804878f: 5d pop %ebp 8048790: c3 ret

  • アセンブリ言語の初歩的な質問です

    xを入れたらx!を返すような階乗のプログラムをアセンブリ言語で作りたいので、頑張っているのですが ADD EAX EBXとすればEAX=EBX+EAXという足し算になりますよね。 そこで掛け算を行うようなものを入力したいのですが EAX*EBXは(掛け算は) MUL EAX EBX とすればいいのでしょうか?

  • アセンブリのプログラムです。

    アセンブリのプログラムで質問があります。cのプログラムのオブジェクトファイルを生成して、objdumpというコマンドでアセンブリ言語を表示させてみたのですが、全然分からなくて、困っています 。どうか、アセンブリプログラムの、解説をよろしくお願いします。できれば、1文1文解説してもらえるとありがたいです。あと、スタックの動き、確保などの解説もあるとありがたいです。よろしくお願いします。 cのプログラム int fact(int p) { if(p<=1) return 1; else return fact(p-1); } アセンブリのプログラム push %ebp mov %esp,%ebp sub $0x8,%esp cmpl $0x1,0x8(%ebp) jg 15 <_fact+0x15> movl $0x1,-0x4(%ebp) jmp 24 <_fact+0x24> mov 0x8(%ebp),%eax dec %eax mov %eax,(%esp) call 0 <_fact> mov %eax,-0x4(%ebp) mov -0x4(%ebp),%eax leave ret nop nop nop

  • C言語->アセンブリ->C言語で構造体渡し

    OS開発をしています。 たとえば、 typedef struct test{ int t1; int t2; int t3; int t4 int t5; }test; という構造体があったとして、 ----アプリケーション---- void main(){ test data; data.t1=100; data.t5=200; testint(data); } ----ライブラリ(アセンブリ)---- _testint: PUSH EBX MOV EBX,ESP INT 0x52 POP EBX RET ----OS側---- int API(int edi, int esi, int ebp, int esp, int ebx, int edx, int ecx, int eax){ test data; data= *(((int *)ebx) + ?); … // ↑ } というプログラムのとき、 ?には、どのような数字を入れれば、 OS側のdataにアプリ側のdataが代入できるでしょうか。 test構造体のサイズは、 20Byteです。 長い質問ですが、回答お願いします。

  • アセンブリ言語について。

    2進数の羅列では人間にはあまりに読み書きしにくいからです。 それを命令単位に区切って、英単語を元にした名前を与えたのが、アセンブリ言語です。 ニーモニックとは、その命令の名前の事です。とはどういう事でしょうか?教えていただけないでしょうか?すみません。 push %ebp mov %esp,%ebp and $0xfffffff0,%esp sub $0x10,%esp mov 0xc(%ebp),%esp : というプログラムで、オペランドが、%ebpなどがそうなのでしょうか?で、このプログラム言語自体をアセンブリ言語というのでしょうか?また、なぜ、低水準言語というのが存在しているのでしょうか?教えていただけないでしょうか?すみません。