実行される順番
プログラムはSSDやHDDなどのストレージに保存されていますが、それを一度メモリーに読み込みます。読み込み終えるとCPUはメモリーから逐次読み込みながら実行していきます
CPUの中にはプログラムを実行するためのカウンターだったり、データを保存するレジスター、計算を行う計算機などが備わっています。
めちゃくちゃ省略していますが、大雑把に言ってこんな感じになっています。
メモリーからプログラムコードを読み込み、ALUで計算などを行います。命令によって計算結果がメモリーに書き出されたりレジスターに入ったりします。
いきなりアセンブリを書くのは難しいですが、それに近い表現ができるCASL言語で試してみましょう。
TEST START
LD GR0, DATA0
LD GR1, DATA1
ADDA GR0, GR1
ST GR0, OUT
RET
DATA0 DC #1
DATA1 DC #2
OUT DS 1
END
LD GR0, DATA0 とあります。これはLD命令と呼ばれるものでメモリーの値をレジスターに書き出す命令です。この例ではDATA0とラベルの付いたメモリーの値(#1)をGR0のレジスターに書き出しています。
LD GR1, DATA1 も同様にDATA1のメモリーの値(#2)をGR1に書き出しています。これでGR0には1が、GR1には2が書き出されたことになります。
次に ADDA があり、これは加算の命令となります。ADDA GR0, GR1 は、GR0 と GR1 の値を加算して GR0 に書き戻す命令です。これで GR0 は 3 になります。
最後に ST 命令ですが、これはレジスターの値をメモリーに書き戻す命令となります。これで OUT とラベルがついたメモリーに3が書き戻されます。
TEST START
LD GR0, DATA0 ; ←DATA0メモリーをGR0レジスターに読み込む(1)
LD GR1, DATA1 ; ←DATA1メモリーをGR1レジスターに読み込む(2)
ADDA GR0, GR1 ; ←GR0とGR1を加算してGR0に書き戻す(1+2=3)
ST GR0, OUT ; ←GR0レジスターをOUTメモリーに書き戻す
RET
DATA0 DC #1 ; ←DATA0メモリー(値は1)
DATA1 DC #2 ; ←DATA1メモリー(値は2)
OUT DS 1 ; ←OUTメモリー(個数は1個)
END
ほとんどのCPUで使用されているx86/x64命令やARM命令なんかも同じような仕組みで動いており、「命令+データ」のセットとなっています。
例えば上の 1+2 を x86/x64 命令で書くとこうなります
MOV rax, 1
MOV rbx, 2
ADD rax, rbx
次にARM命令で書くとこうなります
MOV r0, #1
MOV r1, #2
ADD r0, r0, r1
ARMのADD命令の場合 ADD <格納先> <値0> <値1> となるためちょっと異なりますが、基本的にすべて同じような感じかと思います。ちなみに GPU の命令もこのような感じです。
C言語などで記述したプログラムコードは、コンパイルすることでこのようなアセンブリ言語(x86/x64やARMなど)に変換され実行されていきます。もちろんOSも同じ仕組みで動いています。