アセンブリルラー

コンニーチワ、たけけんです。

釘は熱いうちにという事で、ちょこっとアセンブラをやろうかなと。

まずは基本中の基本から調べてみた。
アセンブラ = C言語で言うとコンパイラのこと
アセンブル = C言語で言うとコンパイルのこと
アセンブリ = C言語で言うとC言語のこと
という事らしい。
妙にややこしい気がするのは気のせいか。

何はともあれ、まずはものまねから始めり。

参考サイト
Let’s Begin Linux
アセンブリをやってみよう!

まずはシステムコール番号を見てみる。

#less /usr/include/asm/unistd_32.h

#ifndef _ASM_X86_UNISTD_32_H
#define _ASM_X86_UNISTD_32_H

/*
* This file contains the system call numbers.
*/

#define __NR_restart_syscall      0
#define __NR_exit                 1
#define __NR_fork                 2
#define __NR_read                 3
#define __NR_write                4
#define __NR_open                 5
#define __NR_close                6
#define __NR_waitpid              7
#define __NR_creat                8

てな感じです。コードの中でいきなり出てくるので、先に軽く目を通しておくのがいいと思ったので、先に記載しておきました。

では参考サイトと、システムコール番号とレジスタの表を見ながら、なんとなしに書いていきました。

$ cat hello.s
.global main

main:
mov $1,         %ebx
mov     $4,             %eax
mov $message,   %ecx
mov     $12,    %edx
int $0x80

mov $1, %eax
int $0x80

.data
message:        .ascii "Hello, World!!\n"

実行結果

$ ./ho
Hello, World#

わりと適当に書いたんだけど、動いてくれた。これがアセンブリか。

ん?ちょっとうまく表示されない!ってちょとわざとらしいかもしれないが。

mov     $12,    %edx

これで12バイト分を確保してるのね。足りてないのだ。

mov     $15,    %edx

こうしてやると、きれいに表示されるのでした。
あまりアセンブラなネタじゃないですけど。

続いて分岐を入れて、ちょっとインデントも入れてみた。

$ cat hello.s
.global main

main:
mov $1,                 %ebx
mov     $4,                     %eax
mov $message,   %ecx
mov     $15,            %edx
int $0x80

mov $100,               %eax
mov $100,               %ebx
cmp     %eax,           %ebx
je hello

end:
mov $1, %eax
int $0x80

hello:
mov     $1,             %ebx
mov $4,         %eax
mov $messages_2,        %ecx
mov $15,                %edx
int $0x80
jmp     end

.data
message:        .ascii "Hello, World!!\n"
messages_2:     .ascii "Goog evening!!\n"

実行結果

$ ./ho
Hello, World!!
Goog evening!!

おお!けっこう適当にやっても動くものだな。
いや、ちゃんとルールにのっかったように適当に書いてもって意味だよ。

しっかり考えて書かないといけないけど、わりと適当でも動いてくれる。そんなイメージだ。
何言ってるかよくわからないかもしれないけど(笑)

あとおもしろいテクニックみたいなのがあった。

xor %ebx, %ebx

xorは排他的論理和  ebxとebxを比較。
同じものと比較なのですべて0です。
すなわち0クリア=初期化。というものらしい。

へえー。
おもしろいね。

じつは参考サイトを結構な数を見て回ったんだけど、なんかどこも分かりづらいなぁと思って、手探りながらも自分でコードを書いていると一気に道が開けた感じです。

 

これはまだサンプルコードをコピペで実行していたときに遭遇したエラーですが、32Bit向け書いたコードゆえのエラーのようでした。
探したけど32BitのISOがなかたので拾ってくることに(笑)

では、積んでるCPUは64Bitで、OSを32Bitにしましたが問題のコードは動くでしょうか。

答えは動きました 

明確な答えは分かりません。
物理CPUがx86-64だからなのか、VMwareが32BitのCPUでエミュレートしているのか。
命令セットを解釈するのはOSでCPUは機械語で動いているから関係ないのかな。
ってのが結論ですが。
物理CPUがIA-64だったらどうなの?っていうよな疑問もつきません。
うーむ??

C言語をやってるとLinuxに詳しくなれると思ってましたが、アセンブラはコンピュータに詳しくなりますね。

なんだか変な感じですけどね。

アセンブラをやっていると、コンピュータってスタックに入れて戻してという作業を繰り返しやっている様子なんだけど、戻しがたくさんあるって事は、その中のどこかで前回やったようなリターンに関数を突っ込むという事はできるのかどうかという事を考えようと思ったけど、とにかく眠くてたまらないので、今度にしようと思う(ノД=)

今度は、グローバル変数は安全じゃない?、とか、オブジェクト指向についてをやろうかなと思ってるので、その辺と合わせてやりたいですね。

ねむー。

 

Similar Posts:


Leave a Reply

Your email address will not be published. Required fields are marked *