seccamp15 応募用紙 選択5
今更であるが以前書いた応募用紙選択2に引き続き選択5を載せようと思う
応募用紙の原稿ファイルの所在を忘れそうなディレクトリに入れてしまったのでなくしても困る
ずいぶんと荒い解答をしたので読む人からすれば雑だろうと思われたと思う
(1)【必須】上記の C 言語のプログラムはどのような動作をしますか。また、この関数を呼び出して利用する main 関数の例を作成してください。
(2)【必須】上記のアセンブリコードを、いくつかのブロックに分割して、おおまかに何をしている部分かを説明してください。もし、上記のアセンブリが気に入らないのであれば、好きなアーキテクチャやコンパイラのアセンブル結果を載せて説明しても良いです。
(1)function関数は引数に渡した数字nをその(数字-1)までのnの倍数を順次配列に格納する動作をする
つまり、
n*0, n*1, n*2, … n*(n-1)
をそれぞれ配列0,1,2,…,n-1番目に格納する。
倍数の配列が出来上がったので、配列の並びを見ると初項0,公差nの等差数列になっているのでこの和を求めるmain文を作成した
以下にそのmain文を掲載する
q5.c
#include<stdio.h>
void function(int *array, int n){
int i;
for(i=0; i<n; i++){
array[i] = i*n;
}
}
int main(){
int j,sum;puts(“どの数字の倍数にするか入力してください”);
int n;scanf(“%d”,&n)
int array[n];
function(array,n);
for(j=0;j<n;j++){
sum += array[j];
}
printf("この等差数列の総和は%d\n",sum);
}
試しに実行した結果を以下に載せる
$ ./a.out
どの数字の倍数にするか入力してください
3
この等差数列の総和は9
(2)
0: 56 push %esi
1: 53 push %ebx
function関数を呼び出されてからesi,ebxレジスタを使用するのでスタックに値を避難させている
2: 8b 5c 24 0c mov 0xc(%esp),%ebx
6: 8b 4c 24 10 mov 0x10(%esp),%ecx
function関数に渡された引数をレジスタに格納する
具体的には%ebxにarray配列のポインタを、%ecxにnの値を格納している
a: 85 c9 test %ecx,%ecx
c: 7e 18 jle 26 <function+0x26>
for文の中でゼロ判定を行うのでゼロフラグをリセットさせるためにtestを行っている
e: 89 ce mov %ecx,%esi
10: ba 00 00 00 00 mov $0x0,%edx
15: b8 00 00 00 00 mov $0x0,%eax
for文の中に突入するための準備を行っている
具体的にはiの0の初期化、配列番号の0の初期化、掛け算を円滑に行うためのnのコピーをしている
1a: 89 14 83 mov %edx,(%ebx,%eax,4)
1d: 83 c0 01 add $0x1,%eax
20: 01 f2 add %esi,%edx
22: 39 c8 cmp %ecx,%eax
24: 75 f4 jne 1a <function+0x1a>
for文の中身
順に配列の番号のシフト、iのインクリメント、掛け算の計算(edxはforを回すたびにn増加しているので事実上掛け算が成立している)、i < nの判定、cmpのフラグから再びforに戻るかbreakするかの命令を行っている
26: 5b pop %ebx
27: 5e pop %esi
28: c3 ret
function関数の冒頭で避難させたレジスタの内容を元に戻してreturnをしている
アセンブリをもっとすらすら読めるようになりたい...