C
1#define M 2#define N 3long arith (long x, long y) 4{ 5long result = x*M + y/N; 6return result; 7}
上記のようなプログラムにいろいろなM とN の整数値を入れてgcc –O –c でコンパイルしてアセンブリ言語ファイル(.o ファイル)を生成し,objdump -dで逆アセンブルすることで.式xM + y/N がどのように計算されるかを見ています.
あるファイルについてこれを行った時.アセンブリ言語で下のように書かれていました.smulhは調べてみたところ,2 つの 64 ビットレジスタ Xn と Xm を乗算し、その 128 ビットの乗算結果の上位 64 ビットをレジスタ (Xd) に書き込む,とのことでしたが,ここではx0に変数x,x1に変数yが入っているので,どうなっているのかよくわからなくなってしまいました.
smulhをただの乗算として考えてみてもsubのところでx1,つまりyを63回算術右シフトして引いていて,よくわからないです.
このふたつではどのようなことが起きているのか教えていただきたいです.
私の考えをアセンブリの下に記しておきます.
0: b205cfe2 mov x2, #0x7878787878787878 // #8680820740569200760 4: f28f0f22 movk x2, #0x7879 8: 9b427c22 smulh x2, x1, x2 c: 9343fc42 asr x2, x2, #3 10: cb81fc41 sub x1, x2, x1, asr #63 14: 8b000020 add x0, x1, x0 18: d65f03c0 ret
最初の命令で.mov命令によって
x2= 0111100001111000011110000111100001111000011110000111100001111000b
次のmovk命令によってx2 =0111100001111000011110000111100001111000011110000111100001111001b
次のsmulh命令によって,x2=8680820740569200761*y
次のasr命令によって
x2=0000111100001111000011110000111100001111000011110000111100001111b * y
###追記
いくつかのケースで試しに実行してみてもsmulhを使う命令は出てきませんでした.
また,このようなケースを通じて,基本的な除算の仕組みはある程度理解していると思っています.
回答2件
あなたの回答
tips
プレビュー